1.作业登录跳转界面
//form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
public slots:
void jump_slot();
private:
Ui::Form *ui;
};
#endif // FORM_H
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
signals:
void jump(); //自定义跳转信号
private slots:
void on_jump_clicked(); //跳转按钮的点击信号
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
//form.cpp
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::jump_slot()
{
this->show();
}
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_jump_clicked()
{
emit jump(); //发射跳转信号
this->close();
}
//main.cpp
#include "widget.h"
#include "form.h" //第二个界面的头文件
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
Form f;
//将第一个界面的信号函数与第二个界面的槽函数连接
QObject::connect(&w,&Widget::jump,&f,&Form::jump_slot);
return a.exec();
}
改变现象:
2.枚举类型
#include <iostream>
using namespace std;
enum Color //枚举是解决魔鬼数字的问题,枚举类型都是整数
{
red, //red=100,red被赋特殊值后,后面的以这个初始值为基准依次累加
//red没有被赋特殊值时默认值为0,按顺序往下累加
orange,
yellow,
green,
blue = 104, //从blue往下是以104按顺序往下排序
pink,
purple,
};
int main()
{
int num;
cout << "请输入num的值:" << endl;
cin >> num;
enum Color c1 = red;
cout << "c1 = " << c1 << endl;
if(num == 104)
{
cout << "blue" << endl;
}
return 0;
}
3.左值与右值
#include <iostream>
using namespace std;
int main()
{
int num = 520;
int &r1 = num; //左值引用 左值引用必须引用有内存空间的
cout << "r1 = " << r1 << " &r1 = " << &r1 << " num = " << num << " &num = " << &num << endl;
int &&r2 = 1314;//右值引用 &&会在堆区给1314申请一个空间
cout <<"r2 = " << r2 << " &r2 = " << &r2 << endl;
//int &&r3 = num; //错的,num是一个左值,不能被 右值引用
int &&r3 = move(num); //用move()函数可以把num强制转化为右值引用,继而可以通过右值引用使用该值
//所以r3的地址与num一致,并没有申请新的空间
cout <<"r3 = " << r3 << " &r3 = " << &r3 << endl;
return 0;
}
运行结果:
4.面试
1.多态、虚函数、纯虚函数
答:多态广义上有静态多态、动态多态(运行时)
静态多态:函数重载、运算符重载
函数重载:函数重载,是实现静态多态的一种方式,能够实现“一名多用”。
函数重载是指函数名相同,形参个数不同或者类型不同,但在同一作用域下。
运算符重载:运算符重载可以让运算符有特殊的意义,应用于更复杂的场景,作用于类对象之间,满足不同的运算需求。
不能重载的运算符
- 成员运算符 .
- 成员指针运算符 ->
- 作用域限定符 ::
- 计算字节大小 sizeof()
- 三目运算符 ? :
动态多态:能够实现“一名多用”
父类的指针或者引用,指向或初始化子类的对象,调用子类对父类重写的函数,进而展开子类的功能。
需要继承和虚函数
- 类中有虚函数时,类里就会有一个虚指针,虚指针也满足继承
- 虚指针在类的最前面,虚指针指向了一个虚函数表,虚函数表里记录了虚函数,包括子类对父类重写的函数。
- 虚指针和虚函数表是实现多态的重要机制。
纯虚函数:没有实际的定义意义,没有实例化的意义,可以设置为纯虚函数,可以在子类里实现。
包含纯虚函数的类称为抽象类,不能实例化。
2.将:“引用”作为函数参数有哪些特点?
由于引用和目标占用同一块空间,在作为参数传递时,不会开辟新的空间,所以效率高,并且传引用实际上就是传变量的空间,所以也没有值传递和地址传递的区别
- 引用必须初始化,指针可以不初始化(野指针),指针可以指向NULL,引用不能为空,引用一定有明确的目标
- 指针可以修改指向,引用一旦指定目标,不能再修改
- 指针在使用前,需要做合理性检查,但是引用不需要
- 指针会另外开辟空间,但是引用不开辟空间,和目标使用同一片空间
- 指针的大小是8byte/4Byte,引用的大小和目标的大小一致
- 有多级指针,没有多级引用(因为引用不是数据类型,指针是数据类型)
- 有指针数组,但是没有引用数组
3.结构体与联合体有哪些区别?
相同点:结构体与联合体都是构造数据类型
可以存放不同的数据类型。
不同点:计算大小的方式不同、对齐方式不一样