C++构造函数初始化列表和普通初始化的区别

0x01 介绍

C++类中有两种方式可以用来初始化成员变量,一种最常见的是在构造函数内部直接对成员函数赋值:

另外一种方式就是通过构造函数的初始值列表来完成初始化:

这种在构造函数后加一个冒号然后初始化的方式叫做构造函数初始值列表,它更优于第一种初始化方式。

0x02 初始值列表的必要性

在以下情况下,必需使用初始值列表方式来初始化:

  • 类成员包含 const 对象时。
  • 在类 A 没有提供默认构造函数且被类 B 包含或者继承时,类 B 必需使用默认初始化方式初始化 A 。

对于第一个条件比较好理解,因为 const 本身在初始化后是无法再赋值的,所以必须使用初始化列表来对其初始化。

对于第二种情况,因为根据构造函数的执行顺序,在构造类 B 时必须先构造类 A 的构造函数,但类 A 并没有提供默认的构造函数,此时导致编译器找不到合适的构造函数,所以对象构造失败。因此这里必须在初始值列表中初始化。

0x02 初始值列表的效率

使用普通方式初始化时编译器会先执行一次对象的默认构造函数,然后才会对其赋值,初始化时执行了两个步骤。

执行 CDog 构造函数时会先执行 CAnimal 的默认构造函数,输出 defualt 然后后才会执行 m_weight = weight 。但是对于初始值列表方式来说并不会执行两步,直接通过相应的构造函数初始化就完成了,相对来说简化了一个过程,效率肯定也会高一些。

0x03 初始化顺序

使用初始值列表初始化时,初始化的顺序是根据成员变量定义的顺序来的,并不是初始值列表的顺序。

实例一个对象 CDog d(1, 2) ,结果会输出:

并不是根据初始值列表先用 2 初始化 m_b,可见初始顺序是根据定义顺序来的。

发表评论