C ++:继承字段的初始化

时间:2010-10-21 04:11:11

标签: c++ initialization initialization-list

我有一个关于在派生类的构造函数中初始化继承成员的问题。示例代码:

class A
    {
public:
    int m_int;
    };

class B: public A
    {
public:
    B():m_int(0){}
    };

此代码给出了以下输出:

In constructor 'B::B()': Line 10: error: class 'B' does not have any field named 'm_int'

(见http://codepad.org/tn1weFFP

我猜这是为什么会这样? m_int应该是B的成员,并且在Am_int的初始化发生时,已经初始化了父类B(因为父构造函数在成员初始化之前运行继承的类)。我的推理错在哪里?这段代码到底发生了什么?

EDIT:我知道初始化这个成员的其他可能性(基础构造函数或派生构造函数中的赋值),但我想理解为什么它在我尝试的方式中是非法的?一些特定的C ++语言功能还是这样的?如果可能的话,请指出C ++标准的段落。

4 个答案:

答案 0 :(得分:20)

你需要为A创建一个构造函数(它可以被保护,所以只有B可以调用它),它就像你一样初始化m_int,然后你调用:A(0) :m_int(0)

你也可以在B的构造函数体中设置m_int = 0。它是可访问的(如您所述),它在特殊构造函数语法中不可用。

答案 1 :(得分:4)

你想要的是这个:

class A{
public:
    A() : m_int(0);
    int m_int;
};

以便m_int在正确的位置初始化。

编辑:

从上面的评论中,当您尝试初始化m_int中的B变量时,编译器抱怨的原因是它已经由A的构造函数初始化。也就是说,你不能重新初始化某些东西,只能重新分配。因此,您可以像上面提到的Ben Jackson一样重新分配,或者您可以在适当的位置进行初始化。

答案 2 :(得分:4)

为了构造类B的实例,首先要实例化类A的实例。在该实例化期间m_int被初始化。在b的构造函数被调用之后的初始化之后,您无法重新初始化m_int。如果这是你的目标,那么你可以为A实现一个构造函数,它接受一个int,然后在B的初始化列表中调用它:

class A
{
public:
  A(int x): m_int(x) {}
  int m_int;
};

class B: public A
{
public:
  B(): A(2) {}
};

答案 3 :(得分:0)

在A中创建一个构造函数 并使用B():A(2){} B()的输入:m_int(0){} 它的工作。