为什么派生 class 可以调用基 class 构造函数两次?
Why can a derived class call base class constructor twice?
我正在学习多重继承和菱形问题,但我很困惑为什么一个基础 class 构造函数可以被调用两次而不会首先出现编译器错误。
示例来自 https://www.geeksforgeeks.org/multiple-inheritance-in-c/
#include<iostream>
using namespace std;
class Person {
// Data members of person
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
int y; \ <- I added this
};
class Faculty : public Person {
// data members of Faculty
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};
class Student : public Person {
// data members of Student
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) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
输出:
Person::Person(int ) called
Faculty::Faculty(int ) called
Person::Person(int ) called
Student::Student(int ) called
TA::TA(int ) called
由于派生的 class TA
两次调用 Person
构造函数,这是否意味着 TA
将具有两个具有相同名称的数据成员副本,例如 int y
?
的两个实例
不打印整数参数,而是尝试打印成员变量的地址。然后用虚拟继承试试,它应该能更好地了解发生了什么。
std::cout << &y << std::endl;
来自 link 的绘图具有误导性,它不是钻石,而是 Y:
---------- ----------
| Person | | Person |
---------- ----------
^ ^
| |
---------- ----------
| Student | | Faculty |
---------- ----------
^ ^
| |
\----- ----/
\ /
|
----------
| TA |
----------
是的,您有两个 Person
成员的副本(Student::y
和 Faculty::y
)。
通过虚拟继承,您拥有的钻石只有一个唯一 Person
。
尝试调查您实例化的 TA 对象的大小。尺寸告诉你什么?对于单个 Person 副本,您期望的大小是多少?两份?
尝试实际访问 y 属性,看看是否出现编译错误!
我正在学习多重继承和菱形问题,但我很困惑为什么一个基础 class 构造函数可以被调用两次而不会首先出现编译器错误。
示例来自 https://www.geeksforgeeks.org/multiple-inheritance-in-c/
#include<iostream>
using namespace std;
class Person {
// Data members of person
public:
Person(int x) { cout << "Person::Person(int ) called" << endl; }
int y; \ <- I added this
};
class Faculty : public Person {
// data members of Faculty
public:
Faculty(int x):Person(x) {
cout<<"Faculty::Faculty(int ) called"<< endl;
}
};
class Student : public Person {
// data members of Student
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) {
cout<<"TA::TA(int ) called"<< endl;
}
};
int main() {
TA ta1(30);
}
输出:
Person::Person(int ) called
Faculty::Faculty(int ) called
Person::Person(int ) called
Student::Student(int ) called
TA::TA(int ) called
由于派生的 class TA
两次调用 Person
构造函数,这是否意味着 TA
将具有两个具有相同名称的数据成员副本,例如 int y
?
不打印整数参数,而是尝试打印成员变量的地址。然后用虚拟继承试试,它应该能更好地了解发生了什么。
std::cout << &y << std::endl;
来自 link 的绘图具有误导性,它不是钻石,而是 Y:
---------- ----------
| Person | | Person |
---------- ----------
^ ^
| |
---------- ----------
| Student | | Faculty |
---------- ----------
^ ^
| |
\----- ----/
\ /
|
----------
| TA |
----------
是的,您有两个 Person
成员的副本(Student::y
和 Faculty::y
)。
通过虚拟继承,您拥有的钻石只有一个唯一 Person
。
尝试调查您实例化的 TA 对象的大小。尺寸告诉你什么?对于单个 Person 副本,您期望的大小是多少?两份?
尝试实际访问 y 属性,看看是否出现编译错误!