gpt4 book ai didi

c++ - 两个父类的构造函数的顺序

转载 作者:行者123 更新时间:2023-12-01 14:15:51 24 4
gpt4 key购买 nike

我对两个版本的代码有一个疑问。
唯一的不同是在父类之间切换虚拟关键字。
有什么原因会发生这种情况吗?
版本一:

#include<iostream> 
using namespace std;
class Person {
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
Person() { cout << "Person::Person() called" << endl; }
};

class Faculty : public Person {
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};

class Student : virtual public Person {
public:
Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}
};

class TA : public Faculty, public Student {
public:
TA(int x):Student(x), Faculty(x), Person(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};

int main() {
TA ta1(30);
}
版本的输出:
Person::Person(int)被称为
Person::Person(int)被称为
Faculty::Faculty(int)被称为
学生::学生(int)叫
TA::TA(int)称为

第二版:
#include<iostream> 
using namespace std;
class Person {
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
Person() { cout << "Person::Person() called" << endl; }
};

class Faculty : virtual public Person {
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};

class Student : public Person {
public:
Student(int x):Person(x) {
cout<<"Student::Student(int ) called"<< endl;
}
};

class TA : public Faculty, public Student {
public:
TA(int x):Student(x), Faculty(x), Person(x) {
cout<<"TA::TA(int ) called"<< endl;
}
};

int main() {
TA ta1(30);
}
输出为:
Person::Person(int)被称为
Faculty::Faculty(int)被称为
Person::Person(int)被称为
学生::学生(int)叫
TA::TA(int)称为

最佳答案

类的初始化顺序基于在类的基类说明符列表中声明的顺序:

  • 如果这是派生最多的类,则将初始化虚拟基类。它们的初始化顺序基于对该类的基类说明符列表的深度优先的从左到右搜索。
  • 非虚拟基类从左到右初始化
  • 此类的成员根据声明顺序
  • 构造
  • 此类的构造函数体运行

  • 对于每个初始化的对象,此过程将递归重复。

    对于第一个示例:
  • TA是派生最多的类,因此首先初始化其Person虚拟基础对象。
  • Person的构造函数主体运行并打印其消息。

  • Faculty是第一个声明的基类,因此接下来对其进行初始化。
  • Faculty具有一个非虚拟基类Person,因此它初始化了自己的Person子对象。
  • Person的构造函数主体运行并打印其消息

  • Faculty的构造函数主体运行并打印其消息

  • Student是下一个基类,因此接下来将对其进行初始化。
  • Student不是派生最多的类,因此它没有获得自己的Person子对象进行初始化。
  • Student的构造函数主体运行并打印其消息

  • TA的构造函数主体运行并打印其消息

  • 结果是,构造函数的主体按以下顺序执行:
  • Person
  • Person
  • Faculty
  • Student
  • TA

  • 对于第二个示例:
  • TA是派生最多的类,因此首先初始化其Person虚拟基础对象。
  • Person的构造函数主体运行并打印其消息。

  • Faculty是第一个声明的基类,因此接下来对其进行初始化。
  • Faculty不是派生最多的类,因此它没有获得自己的Person子对象进行初始化。
  • Faculty的构造函数主体运行并打印其消息

  • Student是下一个基类,因此接下来将对其进行初始化。
  • Student具有一个非虚拟基类Person,因此它初始化了自己的Person子对象。
  • Person的构造函数主体运行并打印其消息

  • Student的构造函数主体运行并打印其消息

  • TA的构造函数主体运行并打印其消息

  • 结果是,构造函数的主体按以下顺序执行:
  • Person
  • Faculty
  • Person
  • Student
  • TA

  • 请注意,在两种情况下,都有两个 Person子对象。为了使 FacultyStudent共享一个 Person子对象,两者都必须从 Person继承,即:
    class Person {
    public:
    Person(int x) { cout << "Person::Person(int) called" << endl; }
    Person() { cout << "Person::Person() called" << endl; }
    };

    class Faculty : virtual public Person {
    public:
    Faculty(int x) : Person(x) {
    cout<<"Faculty::Faculty(int) called"<< endl;
    }
    };

    class Student : virtual public Person {
    public:
    Student(int x) : Person(x) {
    cout<<"Student::Student(int) called"<< endl;
    }
    };

    class TA : public Faculty, public Student {
    public:
    TA(int x) : Student(x), Faculty(x), Person(x) {
    cout<<"TA::TA(int) called"<< endl;
    }
    };
    在这种情况下,逻辑将是:
  • TA是派生程度最高的类,因此其Person虚拟基础对象首先被初始化。
  • Person的构造函数主体运行并打印其消息。

  • Faculty是第一个声明的基类,因此接下来对其进行初始化。
  • Faculty不是派生最多的类,因此它没有获得自己的Person子对象进行初始化。
  • Faculty的构造函数主体运行并打印其消息

  • Student是下一个基类,因此接下来将对其进行初始化。
  • Student不是派生最多的类,因此它没有获得自己的Person子对象进行初始化。
  • Student的构造函数主体运行并打印其消息

  • TA的构造函数主体运行并打印其消息

  • 结果是类的构造函数体按以下顺序执行:
  • Person
  • Faculty
  • Student
  • TA
  • 关于c++ - 两个父类的构造函数的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62557119/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com