首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >成员初始值设定项不命名非静态数据成员或基类

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

Stack Overflow用户
提问于 2013-08-28 12:08:16
回答 1查看 65.9K关注 0票数 47

我很难在谷歌上找到这方面的搜索结果。

代码语言:javascript
运行
复制
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上:

代码语言:javascript
运行
复制
error: member initializer 'm_z' does not name a non-static data member or base class
    b(float z): m_z(z) {}
EN

回答 1

Stack Overflow用户

发布于 2013-08-28 12:22:30

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

C++标准n3337 § 12.6.2/10

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

-首先,并且仅对于最派生类(1.8)的构造函数,虚拟基类按照它们在基类的有向无环图的深度优先从左向右遍历时出现的顺序进行初始化,其中“从左到右”是基类在派生类基说明符列表中的出现顺序。

-然后,直接基类按照在-specifier-list中出现的声明顺序被初始化(不管mem-initializers的顺序如何)。

-然后,非静态数据成员按照它们在类定义中声明的顺序被初始化(同样,不管mem-initializers的顺序)。

-最后,构造函数体的复合语句被执行。

注意:声明顺序是为了确保基对象和成员子对象以与初始化相反的顺序被销毁。-结束注释

因此,您可以在基类中指定构造函数(它可以受到保护),并在派生类初始化列表(should be preferred)中使用该构造函数,或者可以在派生类函数主体中分配给基类成员(不同的行为,不同的效果,效率也较低-您正在分配给默认的初始化(已有值)成员)。

在前一种情况下,你可以这样写:

代码语言:javascript
运行
复制
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;
}
票数 61
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18479295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档