继承 C++ 构造函数 - 谁先调用

inheritance c++ constructor- who called first?

本文关键字:调用 C++ 构造函数 继承      更新时间:2023-10-16

我有这个代码:

class A{
  A *prev, *next, *pLast;
  public:
    A(): prev(NULL), next(NULL)
    {
        pLast->next = this;
        pLast = this;
    }
}
class B: public A
{
   int y;
   public:
   B(int y1) : y(y1) {cout << "in cotr" << endl;}
}

我想知道是否首先调用 A 的构造器(甚至在我插入 y 的值之前)?或者首先 y=y1,然后是 A ctor,最后是 B ctor (打印)谢谢!

在初始化派生类的成员之前首先调用基类构造函数。

初始化顺序明确定义为:

成员初始值设定项在列表中的顺序无关紧要:实际 初始化顺序如下:

1) 如果构造函数用于派生最多的类,则虚拟基 类按它们出现的顺序进行初始化 基类声明的深度优先从左到右遍历 (从左到右是指基本说明符列表中的外观)

2)然后,直接基类按从左到右的顺序初始化为 它们出现在此类的基本说明符列表中

3)然后,非静态数据成员按以下顺序初始化: 类定义中的声明。

4)最后,执行构造函数的主体

因此,对于这种情况,初始化顺序将是 (1) 基类A (2) 成员y (3) B 的构造器主体。

构造函数:基 -> 最派生

析构函数:大多数派生的 -> 基础

这里有一种方法可以在不阅读无休止的标准术语的情况下找出答案(插入一些关于钓鱼和教学的内容)。

您需要在成员初始化期间打印一些内容。
如果您的成员也是类的实例,则可以执行此操作:

struct Member
{
    Member(int i) { cout << "Member initialized" << endl; }
};
struct A
{
    A() { cout << "A initialized" << endl; }
};
struct B : A
{
    B() : member(0) { cout << "B initialized" << endl; }
    Member member;
};
int main()
{
    B b;
}

这打印

A initialized
Member initialized
B initialized

顺便说一句,这是可以使用"逗号运算符"的一种情况,这让我们可以避免额外的类。
像这样写B

struct B : A
{
    B() : member((cout << "Member initializedn", 0)) { cout << "B initialized" << endl; }
    int member;
};

产生相同的输出。
逗号运算符计算其左侧,丢弃结果,并返回右侧。(这里需要一对额外的括号,以免被解释为两个参数。
当您需要跟踪评估但没有明显的方法来插入跟踪时,它可能很有用。