2

据我了解,当我在派生类初始化器列表中初始化基类时,会立即构造基类,然后应该可以使用基类元素。如果这是正确的,为什么这不起作用?

class Base
{
public:
  int elem;
}

class Derived : public Base
{
  Derived() : Base(), elem(1) {}
  // error: class 'Derived' does not have any field named 'elem'
}

注意:就我而言,我无法Base对(它是一个固定的接口类)进行任何更改。

4

5 回答 5

2

构造函数只能构造它自己的类的成员。你需要给Base一个合适的构造函数:

class Base
{
public:
  Base() : elem(23) { }
  int elem;
protected:
  Base(int n) : elem(n) { }
};

class Derived : public Base
{
  Derived() : Base(1) {}
};
于 2013-10-16T14:00:18.533 回答
2

初始化器列表用于初始化该类的直接成员和基子对象,而不是基类的成员。基类成员由基类构造函数初始化,你不能初始化任何东西两次。

如果要在初始化后重新分配基类成员,则可以:

Derived() : Base() {elem = 1;}

或者您可以允许将值传递给基类的构造函数:

explicit Base(int e) : elem(e) {}
Derived() : Base(1) {}

尽管您在问题中添加的注释表明在您的特定情况下这不是一个选项。

于 2013-10-16T14:02:00.827 回答
0

elem 属于 Base 类,因此 Base 负责对其进行初始化。

正确的代码如下所示:

class Base
{
public:
  int elem;
  Base(int n) : elem(n) {}
};

class Derived : public Base
{
  Derived() : Base(1) {}
};
于 2013-10-16T14:00:45.290 回答
0

您只能在初始化列表中初始化类和基类的成员,而不是基类成员。

如果要覆盖基类成员的值,请在构造函数的主体中进行。

于 2013-10-16T14:01:07.957 回答
0

在这种情况下,您不能在初始化器列表中初始化 elem,而必须在函数体中对其进行初始化。

class Base {
 public:
  int elem;
};

class Derived : public Base {
 public:
  Derived() : Base() {
    elem = 1;
  }
};
于 2013-10-16T14:09:22.993 回答