C++初始化列表

原文:https://zhuanlan.zhihu.com/p/33004628

下面我们先看例子

 1 #include <iostream>
 2 using namespace std;
 3 class Base
 4 {
 5 public:
 6     Base(int val)
 7    {
 8        m_num = 0;
 9         cout << "create Base(int val)" << endl;
10     }
11 private:
12     int m_num;
13 };

 

上边的代码,我先定义了一个Base类,并且定义了有一个整型实参的构造函数Base(int val)

 

 1 class BaseChild: public Base
 2 {
 3 public:
 4     BaseChild()
 5     {
 6         m_num = 0;
 7         cout << "create is BaseChild()" << endl;
 8     }
 9 
10 private:
11     int m_num;
12 };
13 
14 int main(int argc, char *argv[])
15 {
16     BaseChild child;
17 }

 

上边的代码继承Base,定义了它的默认构造函数

并且在主函数中创建BaseChild的对象child

编译但报如下错误:

 

C++初始化列表

 

这意思是说,没有Base的默认构造函数。

 

结论1:如果没有定义任何构造函数,C++编译器会自动创建一个默认构造函数。
结论2:如果已经定义了一个构造函数,编译器不会自动创建默认构造函数,只能显式调用该构造函数。

 

在C++中,当创建一个对象时,编译器要保证调用了所有子对象的构造函数,这是C++强制要求的,也是它的一个机制。

 

因为在Base中没有定义默认构造函数,只定义了一个有整型参数的构造函数,因此编译器并不会再去生成一个默认的构造函数,而BaseChild继承Base时,又没有显式地指定Base的构造函数,所以编译报错。

 

如果我们不修改Base,那么,我们用什么办法不去调用默认构造函数,而是显式的调用Base带参构造函数呢。答案就是初始化列表。

 

C++就为我们提供了这样的语法。即在冒号和这个构造函数定义体的左括号之间可指定基类构造函数,如下:

1 BaseChild():Base(1)
2 {
3     cout << "create is BaseChild()" << endl;
4 }

 

现在,再编译程序,轻松通过。

 

当然,初始化列表还可以对类本身的数据成员进行初始化,如对BaseChild成员m_num进行初始化:

 1 BaseChild():Base(1), m_num(0){...} 

中间要以逗号隔开。

 

细心的同学,可能会提问,我们平常见到的都是

int m_num = 0;

而刚刚的代码是m_num(0),这是正确的,我们可以认为这就是调用了int类型的构造函数。类似的,new int(2)是一样的道理。

 

上面是整数类型的赋值,那么,如果是对象之间的赋值呢,例如:

BaseChild child = BaseChild();

其实,这又涉及了另外一个话题,赋值构造函数和编译器的优化。

其具体执行顺序是:

1调用BaseChild构造函数,生成一个临时对象

2给child成员赋值

3创建child对象后,删除临时对象

那么,针对上面的顺序,编译器有可能会优化代码为BaseChild child()直接创建child对象。

 

最后,总结一下初始化列表吧:

1 因为初始化列表中无法直接初始化基类的数据成员,所以你需要在列表中指定基类的构造函数,如果不指定,编译器则会调用基类的默认构造函数。

 

2 推荐使用初始化列表,它会比在函数体内初始化派生类成员更快,这是因为在分配内存后,在函数体内又多进行了一次赋值操作。

 

3 初始化列表并不能指定初始化的顺序,正确的顺序是,首先初始化基类,其次根据派生类成员声明次序依次初始化。

原文链接: https://www.cnblogs.com/lei-zi/p/11121187.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++初始化列表

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/298117

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月15日 下午7:17
下一篇 2023年2月15日 下午7:17

相关推荐