问题描述
我很难在google上找到匹配。
I'm having a hard time finding hits on google for this.
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) {}
};
在clang 3.2上:
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) {}
推荐答案
不能直接从初始化列表初始化基类成员。这是因为初始化顺序是以这种方式进行的。
No you cannot initialize base class members from initializer list directly. This is because order of initialization proceeds in this way
C ++标准n3337 § 12.6.2 / 10
C++ Standard n3337 § 12.6.2/10
- 首先,只有最多的
派生类(1.8)的构造函数,虚拟基类按照
的顺序初始化,它们出现在以深度优先的从左到右遍历的直接
acyclic基类的图,其中从左到右是在导出类
base-specifier-list中的基类的
出现的顺序。
— First, and only for the constructor of the most derived class (1.8), virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where "left-to-right" is the order of appearance of the base classes in the derived class base-specifier-list.
- 然后,直接基类在
声明顺序中初始化,因为它们出现在base-specifier-list
(不考虑mem初始化器的顺序)。
— Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).
- 然后,非静态
数据成员按照在
类定义中声明的顺序初始化 (再次不考虑
mem初始化器的顺序)。
— Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
- 最后,执行
构造函数体的复合语句。
[注意:声明顺序要求确保base和
成员子对象以与
初始化相反的顺序被销毁。 - end note]
[ Note: The declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. — end note ]
因此,您可以在基类中指定一个构造函数派生类(),或者您可以分配给派生类中的基类成员class
So you can specify a constructor in a base class (it can be protected) and use that one in initialization list of derived class (should be preferred) or you can assign to a base class member in derived class ctor body (less efficient - you are assigning to default initialized member).
在前一种情况下,你可以这样写:
In the former case you might write it this way:
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;
}
这篇关于成员初始化器不会为非静态数据成员或基类命名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!