【问题标题】:C++: Initialization of inherited fieldC++:继承字段的初始化
【发布时间】:2010-10-21 04:11:11
【问题描述】:

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

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 的成员,并且在B 中的m_int 初始化发生时,父类A 应该已经初始化(因为父构造函数在继承类的成员初始化之前运行)。我的推理哪里出错了?这段代码到底发生了什么?

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

【问题讨论】:

    标签: c++ initialization initialization-list


    【解决方案1】:

    您需要为 A 创建一个构造函数(它可以受到保护,因此只有 B 可以调用它),它像您一样初始化 m_int,然后在您拥有 :m_int(0) 的地方调用 :A(0)

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

    【讨论】:

    • 这是一个很好的答案,但我只想添加一些解释。当你使用 : 操作符时,你是在告诉编译器在它做任何其他事情之前它应该运行这些指令。基本上,您是在父构造函数(或其他任何东西)运行之前设置一个变量。因此该变量不存在。 :A(), m_int(0) 也应该可以工作。默认情况下,如果不使用 :,编译器将运行基类构造函数。换句话说,如果你什么都不做,C++ 会为你做默认的事情,如果你开始指定事情,它假定你知道你在做什么。
    • 嗯...据我所知,父类的构造函数总是在任何其他初始化之前运行,因此变量m_int 在我尝试初始化它时已经存在。所以这不应该是问题......
    • @Haspemulator 是的,它已经存在,但这就是您收到错误的原因。它已经被 A 的构造函数默认初始化。你不能在 B 的构造函数中重新初始化变量。您可以按照上面 Ben Jackson 的说明 (m_int = 0) 重新分配,到此为止。
    【解决方案2】:

    为了构造类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) {}
    };
    

    【讨论】:

    • 初始化列表中不可用有什么原因吗?我知道初始化此成员的其他可能性(基构造函数或派生构造函数中的赋值),但我想了解为什么我尝试的方式是非法的?一些特定的 C++ 语言功能之类的?如果可能,请指出 C++ 标准中的一段。
    • 这是两件事 - 派生类首先实例化它们的基类,并且成员按照它们被声明的顺序进行初始化,而不是它们在初始化列表中出现的顺序。因此,基类的成员首先被初始化,您不能重新初始化它们。
    【解决方案3】:

    你想要的是这个:

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

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

    编辑:

    根据上面的评论,当您尝试初始化B 中的m_int 变量时,编译器报错的原因是它已经被A 的构造函数初始化了。也就是说,您不能重新初始化某些东西,只能重新分配。因此,您可以像上面所说的 Ben Jackson 那样重新分配,也可以在适当的位置进行初始化。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-27
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 2018-06-26
        • 1970-01-01
        相关资源
        最近更新 更多