• 【C++11】QT开发中常用的C++11特性


    前言

    记录在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}};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    自动推导类型 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";
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    空指针 nullptr
    • C++11之前使用NULL
    • C++11之后使用nullptr
    QPushButton *btn = nullptr;
    
    • 1
    枚举 enum class
    • 使枚举具有作用域
    • 可以指定枚举的底层数据类型,默认为int
    enum class Type {
        Type1,
        Type2,
        Type3
    };
    
    // 指定数据类型为char
    enum class Type : char {
        Type1,
        Type2,
        Type3
    };
    
    // 使用
    Type type = Type::Type1;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    匿名表达式 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;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 在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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    原始字符串

    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
                    )";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 在QT中一般是用来编写样式表的,方便阅读吧
    QString ss = R"(QPushButton {
                    border: none;
                    color: red;
                    background-color: #00ff00;
                    })";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    基于范围的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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    override
    • 修饰函数
    • 检查该函数在父类中是否存在
    // 重写鼠标事件
    protected:
        void mousePressEvent(QMouseEvent *event) override;
        void mouseReleaseEvent(QMouseEvent *event) override;
    
    • 1
    • 2
    • 3
    • 4
    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    final
    • 修饰类的话,表示该类不允许被继承
    • 修饰虚函数的话,表示该虚函数不允许被重写
    default
    • 当类中有自定义的构造函数时,编译器便不会自动生成默认构造函数,需使用default来生成
    class A {
    public:
        A(int i) {
            m_i = i;
        }
        A() = default;  //生成默认构造函数
    
    private:
        int m_i;
    };
    
    A a;     //默认构造函数
    A a1(1); //自定义构造函数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    线程
    智能指针
    • 由于QT的对象树功能,平时挺少用到智能指针的
    • 使用的话也是使用QT提供的智能指针类,可参考下面的博客
    最后

    本文只是记录我在QT开发的过程中使用到的C++11特性的一些基本使用方法,其中更详细的使用方法请阅读博客:c++11新特性,所有知识点都在这了!

  • 相关阅读:
    Python——第7章 pandas数据分析实战
    2022 CCF BDCI 返乡发展人群预测 [0.9117+]
    7.CF438D The Child and Sequence 线段树维护区间取模
    Nginx:负载均衡
    浅谈Kube-OVN
    华卓荣登「2024数商典型应用场景“乘数榜”」
    Batch Normalization的优势
    Android数据存储
    深入分析FragmentPagerAdapter和FragmentStatePagerAdapter
    1414;【17NOIP普及组】成绩(信奥一本通)
  • 原文地址:https://blog.csdn.net/lin786063594/article/details/126904750