成员初始值设定项未命名非静态数据成员或基类

member initializer does not name a non-static data member or base class

本文关键字:静态 数据成员 基类 未命名 成员      更新时间:2023-10-16

我很难在谷歌上找到这方面的点击量。

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) {}
};

关于叮当3.2:

error: member initializer 'm_z' does not name a non-static data member or base class
    b(float z): m_z(z) {}

否,不能直接从初始化器列表初始化基类成员。这是因为初始化顺序以这种方式进行

C++标准n3337§12.6.2/10

在非委托构造函数中,初始化在以下顺序:

--首先,而且只适用于大多数构造函数派生类(1.8),虚拟基类按以下顺序初始化它们出现在有向的从左到右的深度优先遍历中基类的非循环图,其中"从左到右"是基类在派生类中的外观基说明符列表。

--然后,直接基类在中初始化在基说明符列表中出现的声明顺序(不管mem初始化程序的顺序如何)。

--然后,非静态数据成员按照在中声明的顺序进行初始化类定义(同样与mem初始化器)。

--最后构造函数主体被执行

[注:申报令旨在确保成员子对象的销毁顺序与初始化。--尾注]

因此,您可以在基类中指定构造函数(它可以受到保护),并在派生类的初始化列表中使用该构造函数(应该是首选),或者您可以分配给派生类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;
}