构造函数,基类构造函数,初始化列表,成员构造函数的调用顺序

先看一个例子

#include <iostream>

class itemA {
 public:
  itemA() {std::cout << "itemA void constructor" << std::endl;}
  itemA(int m) {std::cout << "itemA param constructor" << std::endl;}
};

class itemB {
 public:
  itemB() {std::cout << "itemB void constructor" << std::endl;}
  itemB(int m) {std::cout << "itemB param constructor" << std::endl;}
  itemB& operator=(int m) {std::cout << "itemB param assign" << std::endl;return *this;}
};

class base1 {
 public:
  base1() {std::cout << "base1 void constructor" << std::endl;}
  explicit base1(int x) {std::cout << "base1 param constructor" << std::endl;}
};

class base2 {
 public:
  base2() {std::cout << "base2 void constructor" << std::endl;}
  explicit base2(int x) {std::cout << "base2 param constructor" << std::endl;}
};

class derived : public base1, base2 {
 public:
  derived() {std::cout << "derived void constructor" << std::endl;}
  derived(int m) : a(m), base2(m){b = 10;std::cout << "derived param constructor" << std::endl;}

 private:
  itemB b;
  itemA a;
};

int main() {
  derived d(3);
  return 0;
}

输出

base1 void constructor
base2 param constructor
itemB void constructor
itemA param constructor
itemB param assign
derived param constructor

结论如下

基类构造函数 > 成员构造函数 > 自身构造函数,至于初始化列表,并不影响构造顺序。

  • 基类的构造顺序只和继承类声明顺序相关,先声明的先执行,初始化列表并不会影响此执行顺序。但想要手动调用基类构造只能写在初始化列表中,因为在进入派生类构造代码块之前,完成基类的构造这一约束条件必须被满足(这一约束对成员构造也成立)。
  • 成员的构造顺序只和成员类声明顺序有关,先声明的先执行,初始化列表并不会影响此执行顺序。
  • 如果打算为一个非基本内置类型的成员变量赋初值,将赋值操作写在初始化列表中要比写在构造函数代码块里面效率更高,这是因为即使写在代码块中也会在进入代码块之前先调用此成员的默认构造,进入代码块后再调用此成员的拷贝构造函数或拷贝赋值函数(如果存在);而直接写在初始化列表只需要调用一次拷贝构造即可。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值