我有以下代码,它利用了初始化列表中的逗号运算符。
#include <iostream>
using namespace std;
class Base
{
protected:
int b;
public:
Base(int a):b(a){}
};
class A:public Base
{
private:
const int i;
const int j;
void inc(int & a, int & b) {a++; b++;}
public:
A(int a, int b):i((inc(a,b),a)),j(b),Base(a+b){}
void print(){cout<<i<<" "<<j<<" "<<b<<endl;}
};
int main()
{
A a(6,7);
a.print();
return 0;
}
我期待结果是:
7, 8, 15
但事实证明是:
7, 8, 13
当用于构造基类时,似乎“a”和“b”没有增加。不知道为什么......
答案 0 :(得分:7)
成员初始化列表中的项目顺序不控制成员初始化的顺序。首先初始化基类,然后按照定义 1 的顺序初始化派生类的成员。
由于基类首先被初始化,Base(a+b)
在调用inc
之前执行,因此它会看到a
和{{1}的值在他们增加之前。
在非委托构造函数中,初始化按以下顺序进行:
- 首先,仅对于派生程度最高的类(1.8)的构造函数,虚拟基类按照它们出现在基类的有向无环图的深度优先从左到右遍历的顺序进行初始化,其中“从左到右”是派生类base-specifier-list中基类出现的顺序。
- 然后,直接基类按声明顺序初始化,因为它们出现在base-specifier-list中(无论mem-initializers的顺序如何)。
- 然后,非静态数据成员按照在类定义中声明的顺序进行初始化(再次与mem-initializers的顺序无关)。
- 最后,执行构造函数体的复合语句。