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

a,c,d 都是申明一个变量,a 非常easy理解就是申明一个变量,b第一感觉是调用构造函数来申明变量。事实上不是,而是申明一个无參数,返回Player的函数。

对于c以为是调用了operator= 赋值运算吧?全然不是。而是先生成一个对象。然后调用Player的拷贝构造函数,生成对象pc。d和c是一样的。e才是真正调用赋值操作。是不是已经被这各式各样的对象申明搞的晕头专向了。如今C++11初始化列表正式登场。
二、简单介绍
     在看C++11初始化前,先来回顾一下C语言中的结构体初始化。代码例如以下:

  1. #include <iostream>
  2.  
  3. struct Player{
  4. int id;
  5. const char* name;
  6. };
  7.  
  8. int main() {
  9. Player player = {10001, "c++"};
  10. printf("%d, %s\n", player.id, player.name);
  11. }

结构体变量能够列表初始化,非常方便。

C++11引入了初始化列表来初始化变量和对象。
三、怎样使用

1、系统内置类型

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

非常明显。还是d 更符合习惯。

  1. std::vector<int> va{1, 2, 3}; // (a)
  2. std::vector<int> vb = {1, 2, 3}; // (b)
  3. std::vector<int> vc(1, 10); // (c)
  4. std::vector<int> vd{1, 10}; // (d)

通过初始化列表能够弥补c中仅仅能初始化同样数字的问题。在使用中c和d不要混淆了。

  1. std::pair<int, const char*> getPlayer() {
  2. return {10001, "c++"};
  3. }
  4. std::map<int, const char*> players = {{10001, "c++"}, {10002, "java”}};

还能够返回pair类型。初始化map都是能够的。

2、自己定义类型
    对于单个參数初始化,类型匹配构造函数,不须要自己定义构造函数。

  1. Player pa{}; // (a)
  2. Player pb; // (b)
  3. Player pc(); // (c)
  4. Player pd(b); // (d)
  5. Player pe = b; // (e)
  6. Player pf = {b}; // (f)

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

3、假设是自己想实现初始化列表构造函数。拷贝函数,赋值函数,须要包括initializer_list 这个头文件。

  1. class MyClass{
  2. public:
  3. MyClass(int a):a_(a){
  4. std::cout << "normal initializer list\n";
  5. }
  6.  
  7. MyClass(std::initializer_list<int> a):b_(a) {
  8. std::cout << "initializer list constructor\n";
  9. }
  10.  
  11. MyClass(MyClass& my) {
  12. std::cout << "copy constructor\n";
  13. this->a_ = my.a_;
  14. this->b_ = my.b_;
  15. }
  16.  
  17. MyClass& operator=(MyClass& my) {
  18. std::cout << "operator = constructor\n";
  19. this->a_ = my.a_;
  20. this->b_ = my.b_;
  21. return *this;
  22. }
  23. private:
  24. int a_;
  25. std::initializer_list<int> b_;
  26. };

这是自己定义类,带有初始化列表构造函数的类,以下来练习下学过的类相关C++知识:

  1. MyClass ma{1}; // (a)
  2. MyClass mb = {1, 2, 3}; // (b)
  3. MyClass mc(2); // (c)
  4. MyClass md = b; // (d)
  5. MyClass me(c); // (e)
  6. MyClass mf{e}; // (f)
  7. auto l{2, 2, 3,3};
  8. MyClass mh{l}; // (e)
  9. 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类型,不可转换

c++11之初始化列表的更多相关文章

  1. C++11的初始化列表

      初始化是一个非常重要的语言特性,最常见的就是对对象进行初始化.在传统 C++ 中,不同的对象有着不同的初始化方法,例如普通数组.POD (plain old data,没有构造.析构和虚函数的类或 ...

  2. C++11初始化列表

    [C++11之初始化列表] 在C++03中,在严格遵守POD的定义和限制条件的结构及类型上可以使用初始化列表(initializer list),构想是结构或是数组能够依据成员在该结构内定义的顺序通过 ...

  3. C++11新特性——初始化列表 initializer_list

    破事水: 由于最近数据结构有个实验报告说是要对字符串进行排序,想偷个懒不想一个一个地赋值,虽然可以用strcpy和传入二级指针的形式直接写,但是这样感觉不美观漂亮. 然后就去膜了一下C++11的新特性 ...

  4. C++-什么时候需要在类的构造函数中使用初始化列表

    1,如果基类没有default构造函数,则意味着其不能自己初始化.如果其被派生,派生类的构造函数要负责调用基类的构造函数,并传递给它需要的参数.下例中Base 2,如果类成员没有默认构造函数.下例中E ...

  5. 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数

    一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一).对象成员及其初始化  C++ Code  1 2 3 4 5 6 7 8 9 1 ...

  6. C++: 类成员初始化列表语法

      类的成员初始化列表的初始化的基本语法,类的构造函数还可以运用此语法为其变量初始化: class Class { private: int a; int b; char ch; public: Cl ...

  7. 初始化列表(const和引用成员)、拷贝构造函数

    一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一).对象成员及其初始化  C++ Code  1 2 3 4 5 6 7 8 9 1 ...

  8. initializer_list、初始化列表、列表初始化

    什么是列表初始化 使用一个花括号来初始化变量,表现形式如下: std::vector<int>a{1,2,3,4,5}; 或者 std::vector<int>a = {1,2 ...

  9. C++中的初始化列表

    C++11扩大了列表初始化的适用范围,使其可以用于所有内置类型和用户定义的类型(即类对象). 1.当列表初始化用于内置类型的变量时,这种初始化形式有一个重要的特点:如果我们使用列表初始化且初始化值存在 ...

随机推荐

  1. 【2017 Multi-University Training Contest - Team 7】Hard challenge

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6127 [Description] 平面上有n个点,每个点有一个价值,每两个点之间都有一条线段,定义 ...

  2. ubuntu-系统密匙

    1.安装虚拟机xp,需要密匙,网上搜了一个,验证能用 MRX3F-47B9T-2487J-KWKMF-RPWBY 2.安装vm也需要密匙,如下可用 HC6JC-FPJ4M-RZM61-48852-2A ...

  3. [Vue + TS] Write a Vue Component as a Class in TypeScript

    Starter app: https://github.com/alexjoverm/Vue-Typescript-Starter Writing Vue components as plain ob ...

  4. log4j配置文件及nutch中的日志配置 分类: B1_JAVA 2015-02-17 10:58 483人阅读 评论(0) 收藏

    吐槽几句,log4j的坑啊.... (1)CLASSPATH中不能有多个log4j的版本本,否则有有奇形怪状的NoSuchMethod, NoSuchFiled, NoClassDefineFound ...

  5. RMAN-03002、RMAN-06059

    使用RMAN备份的时候无法正常备份,抛出以下错误: RMAN-03002: failure of backup command at 04/20/2015 18:55:45 RMAN-06059: e ...

  6. P2P借款的几种情况

    借款,至少出现2种人,借款人和出借人.根据人的性质,企业和个人,分成4种情况. 企业-个人,企业-企业,个人-企业,个人-个人. P2P平台可能出现几种情况: 个人-个人 2种情况:   a. 借款人 ...

  7. 【Android工具类】验证码倒计时帮助类CountDownButtonHelper的实现

    转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 我们在做有关短信验证码功能的时候.为了防止用户无休止的获取短信验证码,或者是误操作.造成验证码混乱的情况.我 ...

  8. thinkphp事务机制

    thinkphp事务机制 一.总结 下面文章也要看,下面有抛出异常(自己提供错误信息那种) 1.事务机制(原子性):所有的事情都完成了就提交,否则回滚.电商里面用的多,付钱买东西的时候. 2.样例(简 ...

  9. 【ALearning】第四章 Android Layout组件布局(二)

    前面我们分别介绍和学习了LinearLayout(线性布局).FrameLayout(单帧布局)和AbsoluteLayout(绝对布局).这次我们要进行RelativeLayout(相对布局)和Ta ...

  10. linux下查看动态链接库依赖关系的命令 x86: ldd *.so arm: arm-linux-readelf -d *.so 实际例子: 以项目中用到的库librtsp.so分析: lijun@ubuntu:~/workspace$ arm-hisiv100nptl-linux-ld -d librtsp.so arm-hisiv100nptl-linux-ld:

    linux下查看动态链接库依赖关系的命令 x86:ldd    *.so arm:arm-linux-readelf    -d    *.so 实际例子:以项目中用到的库librtsp.so分析:l ...