码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • qt下C++11的使用


    简介:

    C++11 是第二个真正意义上的 C++ 标准,也是 C++ 的一次重大升级。C++11 增加了很多现代编程语言的特性,比如自动类型推导、智能指针、lambda 表达式等,这使得 C++ 看起来又酷又潮,一点也不输 Java 和 C#。

    代码案例

    main.cpp
    #include 
    #include 
    
    using namespace std;
    
    /************************************
    *1.auto的应用:
    *描述:自动推导变量类型(只能用于类的静态成员)
    *************************************/
    class A
    {
        public:
        static int getVal()
        {
            return 10;
        }
    };
    
    class B
    {
        public:
        static const char* getVal()
        {
            return "hello";
        }
    };
    
    template 
    auto func()
    {
        auto val = T::getVal();
        return val;
    }
    
    void useAuto()
    {
        /*1.1 在迭代器中使用*/
        QVector v = {2, 4, 6, 8};
        //不使用auto
        for(QVector::iterator it = v.begin(); it != v.end(); it++)
        {
            v.push_back(*it);
        }
        qDebug() << "not use auto v[1]:" << v[1];
    
        //使用auto
        for(auto it = v.begin(); it != v.end(); it++)
        {
            v.push_back(*it);
        }
        qDebug() << "use auto v[1]:" << v[1];
    
        /*1.2 在泛型编程中使用*/
        qDebug() << "A Val: " << func();
        qDebug() << "B Val: " << func();
    }
    
    /************************************
    *2.decltype的应用:
    * 描述:自动推导变量类型(能用于类的非静态成员)
    *************************************/
    template 
    class C
    {
      public:
        void setVal(T& container)
        {
            m_it = container.begin();
        }
        decltype(T().begin()) getVal()
        {
            return m_it;
        }
    
      private:
        decltype(T().begin()) m_it; //使用typename T::iterator m_it,并不能包括所有的迭代器类型,当 T 是一个 const 容器时,会报错
    };
    
    void useDecltype()
    {
        /*2.1在泛型编程中使用*/
        QVector v = {2, 4, 6, 8};
    
        C> obj;
        obj.setVal(v);
        qDebug() << "decltype val:" << *(obj.getVal());
    }
    
    /************************************
    *3.返回值后置运用于泛型编程:
    * 描述:将 decltype 和 auto 结合起来完成返回值类型的推导
    *************************************/
    #include 
    using namespace std;
    
    double foo(int a)
    {
        return (double)a + 0.1;
    }
    
    int foo(double b)
    {
        return (int)b;
    }
    
    template 
    auto Forward(T t) -> decltype(foo(t))
    {
        return foo(t);
    }
    
    void useForward()
    {
        qDebug() << "Forward(2):" << Forward(2);
        qDebug() << "Forward(0.5):" << Forward(0.5);
    }
    
    /************************************
    *4.using的应用:
    * 描述:typedef无法重定义一个模板,using 的别名语法覆盖了typedef的全部功能
    *************************************/
    
    //定义变量类型
    using uint_t = unsigned int;
    
    //定义模板
    template 
    using str_map_t = std::map;
    
    template 
    using func_t = void (*)(T, T);
    func_t xx_2;
    
    /************************************
    *5.类模板可以有默认的模板参数:
    * 描述:typedef无法重定义一个模板,using 的别名语法覆盖了typedef的全部功能
    *************************************/
    template 
    R func(U val)
    {
        return val;
    }
    
    
    void useClassWithDefaultPara()
    {
        func(97);               // R=int, U=int 编译器可以根据实参 97 自行推导出模板参数 U 的类型为 int,并且根据返回值 val=97 推导出 R 的类型也为 int
        func(97);         // R=char, U=int 手动指定了模板参数 R 的类型为 char(默认模板参数将无效),并通过实参 97 推导出了 U = int
        func(97);  // R=double, U=int 手动指定的 R 和 U 的类型值,因此无需编译器自行推导
    }
    
    /************************************
    *6.tuple元组的应用:
    * 描述:实例化的对象可以存储任意数量、任意类型的数据
    *************************************/
    #include 
    using std::tuple;
    
    //给自定义结构体、类实现比较操作符时,
    //下述代码会优先按照第一个字段n进行比较,相等的话进而判断第二个字段,最后到第三个字段,直到能够获得比较的结果为止。
    struct S {
        int n;
        std::string s;
        float d;
        bool operator<(const S& rhs) const {
            return std::tie(n, s, d) < std::tie(rhs.n, rhs.s, rhs.d);
        }
    };
    
    void useTuple()
    {
        //创建一个 tuple 对象存储 10 和 'x'
        std::tuple mytuple(10, 'x');
        //计算 mytuple 存储元素的个数
        int size = std::tuple_size::value;
        //输出 mytuple 中存储的元素
        qDebug() << "size:" << size << std::get<0>(mytuple) << " " << std::get<1>(mytuple);
    
        auto bar = std::make_tuple("test", 3.1, 14);
        //拆解 bar 对象,分别赋值给 mystr、mydou、myint
        const char* mystr = nullptr;
        double mydou;
        int myint;
        //使用 tie() 时,如果不想接受某个元素的值,实参可以用 std::ignore 代替
        std::tie(mystr, mydou, myint) = bar;
    }
    
    /************************************
    *7.统一了初始化方式:
    * 描述:实例化的对象可以存储任意数量、任意类型的数据
    *************************************/
    class Foo
    {
    public:
        Foo(int) {}
    private:
        Foo(const Foo &);
    };
    
    void useInitList()
    {
        Foo a3 = { 123 }; //列表初始化方式,使用了等于号,但私有的拷贝构造并不会影响到它
        Foo a4 { 123 };//  C++11特有
    }
    
    /************************************
    *8.lambda匿名函数的应用:
    * 描述:所谓匿名函数,简单地理解就是没有名称的函数,又常被称为 lambda 函数或者 lambda 表达式
    * []    空方括号表示当前 lambda 匿名函数中不导入任何外部变量
    * [=]   只有一个 = 等号,表示以值传递的方式导入所有外部变量
    * [&]   只有一个 & 符号,表示以引用传递的方式导入所有外部变量
    * [val1,val2,...]   表示以值传递的方式导入 val1、val2 等指定的外部变量,同时多个变量之间没有先后次序
    * [&val1,&val2,...] 表示以引用传递的方式导入 val1、val2等指定的外部变量,多个变量之间没有前后次序
    * [val,&val2,...]   以上 2 种方式还可以混合使用,变量之间没有前后次序
    * [=,&val1,...] 表示除 val1 以引用传递的方式导入外,其它外部变量都以值传递的方式导入
    * [this]    表示以值传递的方式导入当前的 this 指针
    *************************************/
    int all_num = 0;
    void useLambda()
    {
        /*对a 数组中的元素进行排序*/
        int num[4] = {4, 2, 3, 1};
    
        sort(num, num+4, [=](int x, int y) -> bool{ return x < y; });
        for(int n : num){
            qDebug() << "useLambda:" <<  n << " ";
        }
    
        //值传递
        int num_1 = 1;
        int num_2 = 2;
        int num_3 = 3;
        qDebug() << "lambda1:\n";
        auto lambda1 = [=]{
           //全局变量可以访问甚至修改
           all_num = 10;
           //函数体内只能使用外部变量,而无法对它们进行修改
           qDebug() << num_1 << " "
                    << num_2 << " "
                    << num_3;
        };
    
        lambda1();
    
        //借助 mutable 关键字, 可以在lambda2 匿名函数的基础上修改外部变量的值
        auto lambda2 = [=]() mutable{
            num_1 = 10;
            num_2 = 20;
            num_3 = 30;
            //函数体内只能使用外部变量,而无法对它们进行修改
            qDebug() << num_1 << " "
                     << num_2 << " "
                     << num_3;
        };
    
        lambda2();
    
        //引用传递
        auto lambda3 = [&]{
            all_num = 100;
            num_1 = 10;
            num_2 = 20;
            num_3 = 30;
            qDebug() << num_1 << " "
                     << num_2 << " "
                     << num_3;
        };
        lambda3();
    }
    
    /************************************
    *9.非受限联合体(union):
    * 描述:实例化的对象可以存储任意数量、任意类型的数据
    *************************************/
    
    //C++11 删除了联合体不允许拥有静态成员的限制
    /*
    union U {
        static int func() {
            int n = 3;
            return n;
        }
    };*/
    
    /************************************
    *10.for循环的应用:
    * 描述:for (declaration : expression){
                //循环体}
    *************************************/
    void useFor()
    {
        QVector v5 = {2, 4, 6, 8};
        //读写访问
        for(auto& i : v5)
        {
            i++;
        }
        //只读访问
        for(int i : v5)
        {
            qDebug() << "i:" << i;
        }
    }
    
    /************************************
    *11.constexpr的应用:
    * 描述:编译阶段即可计算出结果
    *************************************/
    
    //修饰函数, 只能一条语句
    constexpr int display(int x) {
        //可以添加 using 执行、typedef 语句以及 static_assert 断言
        return 1 + 2 + x;
    }
    
    void useConstexpr()
    {
        //修饰变量
        constexpr int length = 6;
        int url[length] = {1, 2, 3};
        qDebug() << "useConstexpr: url[1]:" << url[1];
    
        qDebug() << "useConstexpr: display(5):" << display(5);
    }
    
    /************************************
    *12.右值引用:
    * 描述:指的是以引用传递(而非值传递)的方式使用 C++ 右值
    *************************************/
    void useRightValue()
    {
        //左值引用
        int num = 10;
        int &b = num; //正确
        //int &c = 10; //错误
    
        //常量左值引用
        int num2 = 10;
        const int &b2 = num;
        const int &c2 = 10;
    
        //右值引用
        int num3 = 10;
        //int && a = num;  //右值引用不能初始化为左值
        int && a = 10;
        a = 100;
        qDebug() << "useRightValue: a:" << a;
    }
    
    /************************************
    *13.move()函数的应用:
    * 描述:该函数并不能移动任何数据,它的功能很简单,就是将某个左值强制转化为右值
    *************************************/
    class demo {
    public:
        demo(int num):num(num){}
        int get_num()&&{  //仅供右值调用
            return this->num;
        }
    private:
        int num;
    };
    
    void useMove()
    {
       demo a(10);
       //qDebug() << a.get_num() << endl;      // 错误
       qDebug() << move(a).get_num() << endl;  // 正确 左值被强制为右值
    }
    
    
    /************************************
    *14.nullptr的应用:
    * 描述:相比 NULL 和 0,使用 nullptr 初始化空指针可以令我们编写的程序更加健壮
    *************************************/
    void isnull(void *c){
        cout << "void*c" << endl;
    }
    void isnull(int n){
        cout << "int n" << endl;
    }
    
    void useNullptr()
    {
        isnull(0);
        isnull(NULL);
        isnull(nullptr);
    }
    
    /************************************
    *14.智能指针的应用:
    * 描述:智能指针主要分为QSharedPointer、shared_ptr(共享的智能指针)、QScopedPointer、unique_ptr(独占的智能指针)和QWeakPointer、weak_ptr(弱引用的智能指针)三种,shared_ptr是使用最多的一种
    * 智能指针可以在适当时机自动释放分配的内存。也就是说,使用智能指针可以很好地避免“忘记释放内存而导致内存泄漏”问题出现
    * 智能指针的核心实现技术是引用计数,每使用它一次,内部引用计数加1,每析构一次内部的引用计数减1,减为0时,删除所指向的堆内存
    *************************************/
    #include 
    #include 
    
    class OnePiece {
    public:
        OnePiece() {
            qDebug() << QString("OP");
        }
        ~OnePiece() {
            qDebug() << QString("~OP");
        }
    public:
        void print() {
            qDebug() << QString("OP Print ");
        }
    };
    
    class Nika : public QObject {
    public:
        Nika() {
            qDebug() << "Nika()";
        }
        ~Nika() {
            qDebug() << "~Nika()";
        }
    
    public:
        void print() {
            qDebug() << "Nika Print";
        }
    };
    
    
    void useSmartPointer()
    {
        //QSharedPointer 与 QWeakPointer(为了监视QSharedPointer)
        QSharedPointer op1 = QSharedPointer(new OnePiece);  //引用计数为1
        QSharedPointer op2(op1);  //引用计数为2
        QSharedPointer op3 = op1;  //引用计数为3
        op3->print();
    
        // 弱引用
        QWeakPointer op4 = op1;  //引用计数为3
        // 弱引用转为强引用
        QSharedPointer op5 = op4.toStrongRef();  //引用计数为4
        QSharedPointer op6 = op4.lock();  //引用计数为5
        op6->print();
    
    
        QSharedPointer op = QSharedPointer(new OnePiece);  //引用计数为1
        OnePiece *op7 = op.data();
        op7->print();
        OnePiece *op8 = op.get();
        op8->print();
    
        QSharedPointer op9 = QSharedPointer(new OnePiece);  //引用计数为1
        QSharedPointer op10(op9);  //引用计数为2
        op10.clear();  //引用计数为1
        if (op10.isNull()) {
            qDebug() << "op10 is null";
        }
    
        //独享指针 没有拷贝构造和赋值构造 独占内存
        QScopedPointer op11(new OnePiece);
        op11->print();
    
        //QPointer 只能使用于继承自QObject的类
        QPointer nika1(new Nika);
        QPointer nika2 = nika1;
        if (!nika1.isNull()) {
            nika1->print();
        }
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        //auto的应用
        useAuto();
    
        //decltype的应用
        useDecltype();
    
        //返回值后置的应用
        useForward();
    
        //类模板可以有默认的模板参数
        useClassWithDefaultPara();
    
        //Tuple元组的应用
        useTuple();
    
        //列表初始化方式
        useInitList();
    
        //lambda匿名函数的应用
        useLambda();
    
        //for循环的应用
        useFor();
    
        //constexpr的应用
        useConstexpr();
    
        //右值引用
        useRightValue();
    
        //nullptr的应用
        useNullptr();
    
        //智能指针的应用
        useSmartPointer();
    
        return a.exec();
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513

    执行结果

    在这里插入图片描述

    参考:http://c.biancheng.net/cplus/11/

  • 相关阅读:
    OpenGL 纹理详解
    kubernetes之crontab
    为什么你的static_assert不能按预期的工作?
    第三章 运算符与标识符与关键字
    工业无线路由器助力打造高速路多功能测速杆
    C#-单例模式
    在 Vite项目中,使用插件 @rollup/plugin-inject 注入全局 jQuery
    Spring Boot中解决跨域问题(CORS)
    什么是跨域?及跨域解决方法
    世微LED 大功率升压恒流驱动芯片 平板显示LED背光板灯串恒流控制器 AP9193
  • 原文地址:https://blog.csdn.net/linyibin_123/article/details/128054090
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号