我有以下代码,它利用初始化列表中的逗号运算符.
#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;
}
Run Code Online (Sandbox Code Playgroud)
我期待结果如下:
7, 8, 15
Run Code Online (Sandbox Code Playgroud)
但事实证明是:
7, 8, 13
Run Code Online (Sandbox Code Playgroud)
当用于构造基类时,似乎"a"和"b"没有增加.不知道为什么......
成员初始化列表中的项目顺序不控制成员初始化的顺序.首先初始化基类,然后按定义1的顺序初始化派生类的成员.
由于基类首先被初始化,所以在调用之前Base(a+b)执行,因此它会看到它们在递增之前和之前的值.incab
在非委托构造函数中,初始化按以下顺序进行:
- 首先,仅对于派生程度最高的类(1.8)的构造函数,虚拟基类按照它们出现在基类的有向无环图的深度优先从左到右遍历的顺序进行初始化,其中"左 - to-right"是派生类base-specifier-list中基类出现的顺序.
- 然后,直接基类按声明顺序初始化,因为它们出现在base-specifier-list中(无论mem-initializers的顺序如何).
- 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管mem-initializers的顺序如何).
- 最后,执行构造函数体的复合语句.