前言
记录在QT开发的过程经常使用到的C++11特性
初始化列表
- 使用花括号{}初始化数据
QVector<int> vec{1, 2, 3};
QMap<int, int> map{{1, 1}, {2, 2}, {3, 3}};
// 习惯了赋值操作,所以一般是这么写
QVector<int> vec = {1, 2, 3};
QMap<int, int> map = {{1, 1}, {2, 2}, {3, 3}};
自动推导类型 auto
- 使用auto来自动推导数据类型
- 为方便阅读,一般基本数据类型就不使用auto啦
- 数据类型较长/匿名函数就会使用auto
auto i = 1; //int类型
auto str = "str"; //QString类型
auto vec = QVector<int>{1, 2, 3}; //容器vector
// 获取vec的迭代器
QVector<int>::iterator it = vec.begin(); //不使用auto需要写这么长的数据类型名
auto begin = vec.begin();
// 匿名函数(有些匿名函数不好判断类型,由系统自行推导)
auto func = []{
qDebug() << "lambda";
};
空指针 nullptr
- C++11之前使用NULL
- C++11之后使用nullptr
QPushButton *btn = nullptr;
枚举 enum class
- 使枚举具有作用域
- 可以指定枚举的底层数据类型,默认为int
enum class Type {
Type1,
Type2,
Type3
};
// 指定数据类型为char
enum class Type : char {
Type1,
Type2,
Type3
};
// 使用
Type type = Type::Type1;
匿名表达式 lambda
- 基本语法
[capture list] (params list) mutable exception -> ret { function body }
[捕获列表] (形参列表) 说明符 抛出异常 -> 返回值 { 函数体 }
- [capture list]:捕获列表,捕获父作用域中的变量来让自己使用;
- (params list):参数列表,可省略;
- mutable:mutable关键字,表示可以修改按值传入的变量的副本(不是值本身);使用mutable关键字后对按值传入的变量进行的修改,不会将改变传递到Lambda表达式之外;一旦使用mutable,参数列表就算没有参数也需要写 ‘()’, 可省略;
- exception:表示Lambda表达式可以抛出指定类型的异常,可省略;
- -> ret:指定函数返回类型,可省略;
- { function body }:函数体。
- 捕获列表
捕获列表的捕获形式:
- [var]:表示值传递的方式捕捉变量var
- [=]:表示值传递方式捕捉所有父作用域的变量(包括this)
- [&var]:表示引用传递方式捕捉变量var
- [&]:表示引用传递方式捕捉父作用域的所有变量(包括this)
- [this]:表示值传递方式捕捉当前的this指针
auto func1 = [] {
qDebug() << "最简单的lambda";
};
auto fun2 = [](int a, int b) {
qDebug() << "a + b = " << a + b;
};
auto fun3 = [](int a, int b) -> int {
qDebug() << "a + b = " << a + b;
return a + b;
};
int a1 = 7;
int a2 = 77;
auto func4 = [a1, &a2] {
++a2;
qDebug() << "a1:" << a1 << "a2:" << a2;
};
- 在QT中的使用一般是用lambda来作为槽函数
QTimer *timer = new QTimer(this);
timer->setInterval(1000);
connect(timer, &QTimer::timeout, this, [ = ] {
qDebug() << "current datetime:" << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
});
timer->start();
原始字符串
R"xxx(原始字符串)xxx" //xxx可省略
- 可解决特殊字符问题
- 字符串换行编写的问题
QString str1 = R"(123)";
QString str2 = R"lin(123)lin";
// 路径 特殊字符\
QString path = R"(C:\Users\Sevenlin\Desktop\)";
QString path1 = "C:\\Users\\Sevenlin\\Desktop\\";
// 字符串换行
QString str3 = R"(123
456
789
)";
- 在QT中一般是用来编写样式表的,方便阅读吧
QString ss = R"(QPushButton {
border: none;
color: red;
background-color: #00ff00;
})";
基于范围的for循环
- 遍历容器中的数据
QList<int> list = {1, 2, 3, 4, 5};
// 值传递的方式
for (auto item : list) {
qDebug() << item;
}
// 引用传递,可修改容器中的值
for (auto &item : list) {
item = item * 2;
}
// const & 引用传递,只读
for (const auto &item : list) {
qDebug() << item;
}
override
- 修饰函数
- 检查该函数在父类中是否存在
// 重写鼠标事件
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
delete
- 修饰函数
- 表示禁用该函数
// 编写单例类时,禁用拷贝构造和赋值构造
class A {
public:
A(const A &a) = delete;
A &operator=(const A &A) = delete;
};
// QT中有宏可以方便使用
#define Q_DISABLE_COPY(Class) \
Class(const Class &) = delete;\
Class &operator=(const Class &) = delete;
#define Q_DISABLE_MOVE(Class) \
Class(Class &&) = delete; \
Class &operator=(Class &&) = delete;
#define Q_DISABLE_COPY_MOVE(Class) \
Q_DISABLE_COPY(Class) \
Q_DISABLE_MOVE(Class)
final
- 修饰类的话,表示该类不允许被继承
- 修饰虚函数的话,表示该虚函数不允许被重写
default
- 当类中有自定义的构造函数时,编译器便不会自动生成默认构造函数,需使用default来生成
class A {
public:
A(int i) {
m_i = i;
}
A() = default; //生成默认构造函数
private:
int m_i;
};
A a; //默认构造函数
A a1(1); //自定义构造函数
线程
- 使用的是QT提供的线程类,没使用过C++11提供的
- QT中线程的使用可参考下面的博客
智能指针
- 由于QT的对象树功能,平时挺少用到智能指针的
- 使用的话也是使用QT提供的智能指针类,可参考下面的博客
最后
本文只是记录我在QT开发的过程中使用到的C++11特性的一些基本使用方法,其中更详细的使用方法请阅读博客:c++11新特性,所有知识点都在这了!