简体   繁体   English

为什么先调用基类构造函数然后派生类构造函数

[英]why first calling base class constructor and then derived class constructor

According to c++ rules, when defining a derived class object, the base class constructor is called to initialize the base class members and then the derived class constructor. 根据c ++规则,在定义派生类对象时,将调用基类构造函数来初始化基类成员,然后初始化派生类构造函数。 For the destructor, the rule reverts. 对于析构函数,规则会恢复。

I'm wondering why this rule should be obeyed. 我想知道为什么要遵守这条规则。 Why first base constructor and then derived class constructor? 为什么第一个基础构造函数然后派生类构造函数? Is there any reason for doing this? 这样做有什么理由吗? or just because it's the definition of c++. 或者只是因为它是c ++的定义。

Thanks, 谢谢,

because members of the derived class may depend on members of the base class, members of the base class have to be initialized first. 因为派生类的成员可能依赖于基类的成员,所以必须首先初始化基类的成员。

You can't argue the opposite. 你不能争论相反。

An object of class type consists of subobjects - its base class subobjects and (non-static) data members. 类类型的对象由子对象组成 - 其基类子对象和(非静态)数据成员。

Before a subobject is constructed, in its place is raw uninitialized storage, which you must not use as an object. 在构建子对象之前,在其位置是原始的未初始化存储,您不能将其用作对象。

The subobjects of an object are constructed before the body of the constructor for the object is entered, so that you can use these subobjects in the constructor body. 在输入对象的构造函数的主体之前构造对象的子对象,以便可以在构造函数体中使用这些子对象。

That base class subobjects are constructed before member subobjects is just a rule, but may be motivated by the following observations: 在成员子对象只是一个规则之前构造了这个基类子对象,但可以通过以下观察来激励:

  • A derived object is a base object and adds additional members and behaviors. 派生对象基础对象,并添加其他成员和行为。 It seems natural to first construct the base part on which the derived part rests, before adding the new parts. 在添加新零件之前,首先构造派生零件所依赖的基础零件似乎很自然。
  • When the base class subobject is constructed, you can use it (except for polymorphic behavior) through it regular interfaces, including in the initialization of data members. 构造基类子对象时,可以通过常规接口使用它(多态行为除外),包括数据成员的初始化。 The converse is not true: you can't access derived class members the regular way (through encapsulating member functions) until the derived object is fully constructed (which includes the base class subobjects. 反之亦然:您无法以常规方式(通过封装成员函数)访问派生类成员,直到派生对象完全构造(包括基类子对象)。

A technical reason for this construction order is that compilers typically initialize the data needed for polymorphism (vtable pointers) in constructors. 此构造顺序的技术原因是编译器通常初始化构造函数中的多态(vtable指针)所需的数据。 So first a base class constructor initializes this for its class, then the derived class constructor overwrites this data for the derived class. 因此,首先基类构造函数为其类初始化此函数,然后派生类构造函数将覆盖派生类的此数据。 This also corresponds to the rules for behavior of polymorphic functions in constructors. 这也对应于构造函数中多态函数的行为规则。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM