学习视频链接
csdn - 安全中心https://link.csdn.net/?target=https%3A%2F%2Fwww.bilibili.com%2Fvideo%2FBV1g4411H78N%3Fp%3D14
一、Lambda表达式简介
1.1 简介
C++11 中的 Lambda 表达式用于定义并创建置名的函数对象,以简化编程工作
1.2 QT中使用的注意事项
5.0 版本之前需要添加这一句话,表示使用 C++11 的特性。否则使用不了 lambda 表达式。
高版本默认加上这个东西了
二、语法
2.1 函数声明
在 lambda 表达式中,写一个内容。如果 [] 为空,则这里面的内容不能获取到外面的变量,所以会报错。
加上一个 = 就可以访问到所有外面的变量。
但是这里并没有修改按钮中显示的内容,因为这个只是一个函数声明,我们需要调用这个函数才能够修改按钮样式
2.2 []中的参数
空。没有使用任何函数对象参数。
=。函数体内可以使用Lambda所在作用范圈内所有可见的局部交量 (包括Lambda所在类的 this),并且是值传递方式 (相当于编译器自动为我们按值传递了所有局部变量)。
&。函数体内可以使用 Lambda 所在作用范图内所有可见的局部交量 (包括 Lambda 所在类的 this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部交量)
this。函数体内可以使用 Lambda 所在类中的成员交量
a。将 a 按值进行传递。按值进行传递时,函数体内不能修改传递进来的 a 的拷贝,因为默认情况下函数是 const 的。要修改传递进来的 a 的拷贝,可以添加 mutable 修饰符
&a。 将 a 按引用进行传递.
a,&b。将 a 按值进行传递,b 按引用进行传递
=,&a,&b。除 a 和 b 按引用进行传递外,其他参数都按值进行传送
&,a,b。除 a 和 b 按值进行传递外,其他参数都按引用进行传递
2.3 函数调用
2.4 测试其他参数
下图中,只有 btn 能传入进 lambda 表达式
2.5 操作符重载函数参数
标识重载的 () 操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:&a, &b))两种方式进行传递
三、与 connect 结合
3.1 可修改标示符 mutable
mutable 声明,这部分可以省略。按值传递函数对象参数时,加上 mutable 修饰符后,可以修改按值传递进未的拷贝 (注意是能修改拷贝,而不是值本身)
3.2 代码
注意:如果没有写 mutable 则 m = 100 + 10; 这句话会报错,因为 m 是值传递进来的,也是不可修改的
#include "widget.h"
#include <QDebug>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton *btn = new QPushButton("上课", this);
// 重置窗口大小
this->resize(600, 400);
QPushButton *btn2 = new QPushButton("第二个按钮", this);
btn2->move(100, 100) ;
int m = 10;
connect(btn, &QPushButton::clicked, this, [m] ()mutable { m = 100 + 10; qDebug() << m; });
connect(btn2, &QPushButton::clicked, this, [=] () { qDebug() << m; });
}
void Widget::ClassIsOn()
{
emit zt->teach("数学");
}
Widget::~Widget()
{
qDebug() << "Widget的析构调用";
}
四、函数的返回值
int ret = [] ()->int{return 1000;}();
-> 返回值类型,标识函数返回值的类型,当返回值为 void,或者函数体中只有一处 return 的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略
五、函数体
{},标识函数的实现,这部分不能省略,但函数体可以为空
六、利用 Lambda 表达式实现按钮关闭窗口
6.1 代码
#include "widget.h"
#include <QDebug>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
// 创建一个老师的对象
this->zt = new Teacher(this);
// 创建一个学生的对象
this->st = new Student(this);
void(Teacher:: *teacherSignal)(QString) = &Teacher::teach;
void(Student:: *studentSlot)(QString) = &Student::learn;
connect(zt, teacherSignal, st, studentSlot);
ClassIsOn();
// 点击一个 上课按钮,再触发上课
QPushButton *btn = new QPushButton("关闭", this);
// 重置窗口大小
this->resize(600, 400);
//利用lambda表达式实现点击按钮关闭窗口
btn->move (100,0) ;
connect(btn, &QPushButton::clicked, this, [=] () {
this->close() ;
emit zt->teach("语文");
});
}
void Widget::ClassIsOn()
{
emit zt->teach("数学");
}
Widget::~Widget()
{
qDebug() << "Widget的析构调用";
}