我很难在google上找到点击率。
struct a {
float m_x;
float m_z;
public:
a(float x): m_x(x) {}
};
class b : public a {
b(float z): m_z(z) {}
};
on clang 3.2:
error: member initializer 'm_z' does not name a non-static data member or base class
b(float z): m_z(z) {}
答案 0 :(得分:39)
不,您无法直接从初始化列表初始化基类成员。这是因为初始化顺序以这种方式进行
C ++标准版n3337 § 12.6.2 / 10
在非委托构造函数中,初始化继续进行 以下顺序:
- 首先,仅适用于最多的构造函数 派生类(1.8),虚拟基类按顺序初始化 它们出现在深度优先的从左到右的遍历中 基类的非循环图,其中“从左到右”是基数的顺序 派生类中基类的外观 基本符列表。
- 然后,初始化直接基类 声明顺序,因为它们出现在base-specifier-list中 (不管mem-initializers的顺序如何)。
- 然后,非静态 数据成员按照在其中声明的顺序进行初始化 类定义(再次无论顺序如何 MEM-初始化)。
- 最后,复合语句 构造函数体被执行。
[注:声明命令的目的是确保基础和 成员子对象以相反的顺序销毁 初始化。 - 结束说明]
因此,您可以在基类中指定构造函数(它可以受到保护)并在派生类(should be preferred)的初始化列表中使用该构造函数,或者您可以将分配给基础派生类ctor体中的类成员(不同的行为,不同的效果以及效率也较低 - 您将分配给默认的初始化(已有值)成员)。
在前一种情况下,您可以这样写:
struct A {
float m_x;
float m_z;
A(){}
protected:
A(float x): m_x(x) {}
};
class B : public A {
public:
B(float z) : A(z) {}
// alternatively
// B(float z) {
// m_x = z;
// }
};
int main(){
B b(1);
return 0;
}