Qt学习笔记
C++回顾
指针
指针是为了运行效率,不是为了好用
- 声明:
int *p = &a
- 指向常量的指针:
const int *p;
- 常指针:
int *const p
- 指针数组:
int *p[3]
- 指向数组的指针:
int (*p)[3]
- 指向指针的指针:
int **p
- 动态获取空间:
p = new int[3]
- 删除:
deleta p
或delete [] p
- 引用:变量的别名,是一种隐式的指针,
int &p = a
,区别在于引用必须在声明时初始化,不能指向其他对象,在许多情况下代替指针使用。
类
元素的访问性:
private:
默认,外部不可访问public:
外部可以访问protected:
子类可以访问。通过在类中声明友元friend
可以使外部函数访问private
和protected
元素。构造函数:与类同名,没有返回类型,有初始化列表
1
Complex(double r, double i): real(r), imag(i){}
- 析构函数:
~
+类名,没有返回类型,注意删除指针释放内存
1
~Complex(){}
- 拷贝构造函数:以该类的对象的不可变引用为参数
1
Complex(const Complex &c){}
- 继承:C++允许多继承,父类前需要表明继承方式
1
2
3class neet: public teen, public player{
...
}
模板
C++常用的泛型机制,可以使函数或类适用于不同类型
1 | template <typename T> |
在使用时声明具体的类型
1 | vector<int> a = {1, 2, 3}; |
模板不仅可以用于类型的多态化,但其他用法并不常见。
一些较新的功能
- 智能指针:指针最常见的问题是内存泄漏和野指针,采用智能指针可以避免这类问题。其中
unique_ptr
有所有权系统,不允许直接拷贝,并且可以阻止野指针出现。而shared_ptr
允许多指针指向同一个地址,但是通过计数器防止多次删除,shared_ptr
较为常用。
1
2
3
4
5
6
7
8
using namespace std;
shared_ptr<int> p1(new int(3));
shared_ptr<int> p2 = new int; // 错误,不能直接把普通指针赋给智能指针
shared_ptr<int> p3 = make_shared<int>(100);
shared_ptr<int> p4 = p1;
int *Pint = p1.get(); // 获取原始指针;
// 引用计数器归零之后自动销毁;
新的列表容器:
vector<T>
,array<T>
。其中vector
可变长度,允许插入;array
固定长度。支持迭代,更加安全。作用于可迭代对象的
for
循环:
1
2
3
4int a[] = {0, 1, 2, 3, 4, 5};
for (int i : a)
std::cout << i << ' ';
std::cout << '\n';
- 类型推断:将
auto
作为类型声明的关键字。
Qt基本使用
信号与槽
当某种事件发生时,会调用相应的信号函数,而收到信号后对应的槽函数便会启动。信号与槽是多对多的关系,需要采用连接函数结合起来:
1 | connect(sender, SIGNAL(signal()), receiver, SLOT(slot())); |
sender
和receiver
是两个指针。
有多种方法连接信号与槽:
Design界面连接:在“编辑信号与槽”的状态下可以直接连接,仅适用于不取参数的简单槽函数,方便,但是能完成的操作有限。连接函数在工程文件中看不到,实际上位于编译后得到的
ui_mainwindow.h
当中。特别的,把箭头引到mainwindow
时是可以输入自定义的槽函数名的。Design界面新建:使用控件右键菜单中的“转到槽”可以为信号新建
mainwindow
上的槽函数:
1
void MainWindow::on_pb_ok_clicked(){}
能完成各种操作,但是不能新建控件级别的槽函数,不太方便复用。连接函数在工程文件中看不到,实际上在编译后得到的moc_mainwindow.cpp
中使用更加底层的方法进行了连接。
- 手动新建:手动编写需要注意三点:在
mainwindow.h
的private slots:
下声明槽函数原型;在mainwindow.cpp
定义槽函数;采用Design界面连接的方法配置连接。也可以在mainwindow.cpp
中mainwindow
的构造函数内手动调用连接函数,注意此时receiver
要写this
。连接函数也可以采用Design界面连接的方法配置。
1
2
3
4
5
6
7
8
9
10
11[mainwindow.h]
class MainWindow : public QMainWindow{
...
private slots:
void reset();
...
}
[mainwindow.h]
void MainWindow::reset(){
...
}
这样也可以把带参数的默认函数作为槽函数了,但是只能是信号函数和槽函数参数一致的前提下
1
connect(ui->lineEdit, SIGNAL(textEdited(QString)), ui->label, SLOT(setText(QString)))
此外,也可以通过新建控件类的子类来为控件新建槽函数(待确认)。
总的来说,以目前的水平手动写connect函数有些困难,还是使用可视化操作较为容易。
其他
- Qt新定义的容器:可变长度的列表
QList
和QVector
(仅数据存储方式不同);集合QSet
;字典QMap
。QList, QVector, QSet
都接受流插入运算符。