简体   繁体   English

为什么不能在派生类的构造函数初始化列表中初始化基类的数据成员?

[英]Why can't Initialize the data member of base class in the constructor initializer list of derived class?

such is the code,and with the error:"illegal member initialization: 'a' is not a base or member",what is the meaning of the error info,and why?? 这就是代码,并带有错误:“非法成员初始化:'a'不是基础或成员”,错误信息的含义是什么,为什么?

class A{
public:
int a;
};
class B:public A{

public:
B();
};

B::B():a(10){    // put  "a(10)" into the constructor body is right

}

By the time the constructor of the derived class is invoked, the base class must already be constructed. 在调用派生类的构造函数时,必须已经构造了基类。 So it's already too late. 所以现在已经太晚了。 To see why it must be this way, consider: 要了解为什么必须这样,请考虑:

class Base
{
    public:
    int i;
    Base(int q) : i(q) { ; }
};

class Middle : public Base
{
    public:
    Middle() : Base(2) { printf("i=%d\n", i); }
};

class Derived : public Middle
{
    public:
    Derived() : i(3) { ; }
}

Now, think about it. 现在,想一想。 The Middle constructor has to run before the Derived constructor. Middle构造函数必须在Derived构造函数之前运行。 And the Middle constructor ensures that i is 2. So how can the Derived constructor later re-construct it with a different value? Middle构造函数确保i是2.那么Derived构造函数如何能够在以后使用不同的值重新构造它?

See this answer for a more complete explanation of what's going on here. 请参阅此答案 ,以获得有关此处发生的更完整的解释。 Basically, you cannot initialise A::a in the initialiser of B , because it is ill-formed according to the standard. 基本上,你不能在B的初始化中初始化A::a ,因为它根据标准是不正确的。

Because the base class may want to initialize things its own way. 因为基类可能希望以自己的方式初始化事物。 The proper method is to call on of the base constructors in the initializer list and let the base ctor initialize itself. 正确的方法是调用初始化列表中的基础构造函数,并让base ctor初始化自己。

One more important piece of information - remember that if a class does not initialise a member object via the constructor initialization list, then the default constructor for that member will be invoked before that first statement in the base class constructor is executed. 一个更重要的信息 - 记住,如果类没有通过构造函数初始化列表初始化成员对象,那么在执行基类构造函数中的第一个语句之前,将调用该成员的默认构造函数。 When you use the initialiser, what you are actually doing is specifying a constructor to be used INSTEAD of the default constructor. 当您使用初始化器时,您实际执行的是指定要使用默认构造函数的INSTEAD的构造函数。

Clearly when you are constructing a derived class, the parent class member has thus already been constructed, so you cannot reconstruct the base member again, which is what you are trying to do in this example by including it in the derived class initialisation list. 显然,当您构造派生类时,父类成员已经被构造,因此您无法再次重构基本成员,这是您在此示例中尝试通过将其包含在派生类初始化列表中而执行的操作。

As an aside, if you all you want is to have the derived class be able to set the value of A::a to a specific value, then use the following code instead: 顺便说一句 ,如果你想要的是派生类能够将A :: a的值设置为特定值,那么请使用以下代码:

B::B()
{
    a = 10;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么不能在类的构造函数的初始化列表中初始化ifstream? - Why can't I initialize an ifstream in the initializer list of the constructor of a class? 为什么需要在派生类的初始化列表中调用基类的构造函数? - Why the constructor for a base class needs to be called in the initializer list of the derived class? 派生 class 构造函数初始值设定项列表中的基本 class 默认构造函数 - Base class default constructor in derived class constructor initializer list 如何从派生的构造方法初始化列表初始化模板基类的成员? - How to initialize members of template-base class from derived constructor initializer list? 派生类:在初始化列表中使用基类成员 - Derived class: using Base class member in initializer list 如何在派生类构造函数中初始化基类成员变量? - How can I initialize base class member variables in derived class constructor? 当我希望调用基类构造函数时,如何在派生类中初始化成员const引用? - How can I initialize a member const reference in a derived class, when I wish to call a base class constructor? 为什么派生类的构造函数在初始化列表中使用基类的默认构造函数? - Why should a derived class's constructor use the base's default constructor in it's initializer list? 基 class 有时可以初始化派生类的成员吗? - Can a base class sometimes initialize a derived class's member? 初始化列表:基类的构造函数和成员函数 - initializer list: a constructor from the base class and a member function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM