【问题标题】:C++ error initializing base class data member in the derived class member initialization listC++ 在派生类成员初始化列表中初始化基类数据成员时出错
【发布时间】:2014-06-06 10:34:41
【问题描述】:

我有一个关于 C++ 行为的小问题。当我尝试使用派生类的构造函数初始化列表初始化基类的数据成员时,出现错误。 但是,如果我在派生类构造函数中进行初始化,或者如果我使用派生类成员初始化列表中的参数调用基类构造函数,则不会出现错误。所以问题是为什么我在第三种情况下会出错。

class A {
protected:
   int data;
public:
   A(int i = 0) : data(i) {}
};
class B : public A {
public:
   B(int i = 0) { data = i; } /* works fine, initializing inside c'tor definition */
   B(int i = 0) : A(i) {} /* calling super class constructor with arg works fine */
   B(int i = 0) : data(i) {} /* error: class B does not have any field named data */
};
int main() {
    B obj1(7);
    B* obj2 = new B(8);    
    A* obj3 = new B(9);
    delete obj2; 
    delete obj3;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    这是因为您无法在派生类中初始化基类成员。你所说的“构造函数内部的初始化”不是初始化,它是成员已经被基类的构造函数初始化之后的赋值。

    【讨论】:

      【解决方案2】:

      data 在我们到达 B 的初始化列表时已经由 A 的构造函数初始化(如果存在,则在基本构造函数调用之后的部分)。您不能初始化两次。您可以告诉 A 的构造函数如何对其进行初始化,或者将其他内容分配给已经初始化的成员。

      【讨论】:

      • 那么当你在派生的成员初始化列表中显式调用带有参数的基类构造函数时,是不是又一次初始化了同一个数据成员?因为 A 的构造函数在到达这个空间之前就已经被调用了。看起来不像初始化两次?
      • @IbrahimQuraish 不。你说“A 的构造函数在到达这个空间之前就已经被调用了”,但这是错误的。如果您显式调用它,那么 A 的构造函数将使用您提供的参数运行,然后初始化列表的其余部分完成。
      猜你喜欢
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      • 2019-09-10
      • 2023-03-31
      • 1970-01-01
      • 2017-08-30
      • 1970-01-01
      相关资源
      最近更新 更多