zoukankan      html  css  js  c++  java
  • c++11之初始化列表

    一、前言
         C++的学习中,我想每个人都被变量定义和申明折磨过,比如我在大学笔试过的几家公司,都考察了const和变量,类型的不同排列组合,让你区别有啥不同。反正在学习C++过程中已经被折磨惯了,今天再来看看重温下那段“辉煌的历史”。先来看一段代码:
        Player pa;                              // (a)
        Player pb();                            // (b)
        Player pc = Player();                   // (c)  
        Player pd(Player());                    // (d)    
        pd = Player()                           // (e)


    a,c,d 都是申明一个变量,a 很容易理解就是申明一个变量,b第一感觉是调用构造函数来申明变量,其实不是,而是申明一个无参数,返回Player的函数。对于c以为是调用了operator= 赋值运算吧?完全不是,而是先生成一个对象,然后调用Player的拷贝构造函数,生成对象pc。d和c是一样的。e才是真正调用赋值操作。是不是已经被这各式各样的对象申明搞的晕头专向了。现在C++11初始化列表正式登场。
    二、简介
         在看C++11初始化前,先来回忆一下C语言中的结构体初始化,代码如下:
    #include <iostream>
    
    struct Player{
        int id;
        const char* name;
    };
    
    int main() {
        Player player = {10001, "c++"};
        printf("%d, %s
    ", player.id, player.name);
    }

         结构体变量可以列表初始化,非常方便。C++11引入了初始化列表来初始化变量和对象。
    三、如何使用

         1、系统内置类型

        int ia{1};                // (a)
        int ib = {1};             // (b)   
        int ic(1);                // (c) 
        int id = 1;               // (d)

        很明显,还是d 更符合习惯。
        std::vector<int> va{1, 2, 3};          // (a)
        std::vector<int> vb = {1, 2, 3};       // (b)    
        std::vector<int> vc(1, 10);            // (c)   
        std::vector<int> vd{1, 10};            // (d)  
     
        通过初始化列表可以弥补c中只能初始化相同数字的问题。在使用中c和d不要混淆了。
        std::pair<int, const char*> getPlayer() {
             return {10001, "c++"};
         }
        std::map<int, const char*> players = {{10001, "c++"}, {10002, "java”}};
    
        
        还可以返回pair类型,初始化map都是可以的。

        2、自定义类型
        对于单个参数初始化,类型匹配构造函数,不需要自定义构造函数。
        Player pa{};                    // (a)
        Player pb;                      // (b)  
        Player pc();                    // (c)
        Player pd(b);                   // (d)
        Player pe = b;                  // (e)
        Player pf = {b};                // (f)



        对于上面几种变量初始化,推荐a, 如果是带参数的构造函数,推荐b,若果是不带参数的构造函数。

         3、如果是自己想实现初始化列表构造函数,拷贝函数,赋值函数,需要包含initializer_list 这个头文件。
    class MyClass{
    public:
        MyClass(int a):a_(a){
            std::cout << "normal initializer list
    ";
        }
    
        MyClass(std::initializer_list<int> a):b_(a) {
            std::cout << "initializer list constructor
    ";
        }
    
        MyClass(MyClass& my) {
            std::cout << "copy constructor
    ";
            this->a_ = my.a_;
            this->b_ = my.b_;
        }
    
        MyClass& operator=(MyClass& my) {
            std::cout << "operator = constructor
    ";
            this->a_ = my.a_;
            this->b_ = my.b_;
            return *this;
        }
    private:
        int a_;
        std::initializer_list<int> b_;
    };


    这是自定义类,带有初始化列表构造函数的类,下面来练习下学过的类相关C++知识:
        MyClass ma{1};               // (a)
        MyClass mb = {1, 2, 3};      // (b)
        MyClass mc(2);               // (c)
        MyClass md = b;              // (d)
        MyClass me(c);               // (e)
        MyClass mf{e};               // (f)
        auto l{2, 2, 3,3};
        MyClass mh{l};               // (e)
        ma = mb;                     // (h)



    看一下每次调用都输出什么结果,答案在这里:

    initializer list constructor

    initializer list constructor

    normal constructor list

    copy constructor

    copy constructor

    copy constructor

    initializer list constructor

    operator = constructor


    四、为啥需要初始化列表
    1、避免类申明对象混淆,区分对待,对于C++为啥有小括号初始化对象这一说,大家可以自行google,看来不管是谁都有犯错误的时候,勇于承认错误还是好同志。
    2、在初始化多个变量时方便
    3、避免数据切割,因为通过初始化列表是不允许隐式转换的,相关知识可以参考我的这篇文章

    五、注意事项
    1、在申明变量的时候,少用小括号,程序可读性更高
    2、使用初始化列表防止隐式转换,减少bug
    3、通过 {} 返回的对象是const类型,不可转换
  • 相关阅读:
    希腊字母写法
    The ASP.NET MVC request processing line
    lambda aggregation
    UVA 10763 Foreign Exchange
    UVA 10624 Super Number
    UVA 10041 Vito's Family
    UVA 10340 All in All
    UVA 10026 Shoemaker's Problem
    HDU 3683 Gomoku
    UVA 11210 Chinese Mahjong
  • 原文地址:https://www.cnblogs.com/fengju/p/6174296.html
Copyright © 2011-2022 走看看