[英]Why can a derived class call base class constructor twice?
我正在學習多重繼承和菱形問題,但我很困惑為什么基類構造函數可以被調用兩次而不會首先出現編譯器錯誤。
示例來自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
由於派生類TA
兩次調用Person
構造函數,這是否意味着TA
會有兩個同名數據成員的副本,例如int y
兩個實例?
從鏈接中提取是誤導性的,它不是菱形,而是 Y:
---------- ----------
| Person | | Person |
---------- ----------
^ ^
| |
---------- ----------
| Student | | Faculty |
---------- ----------
^ ^
| |
\----- ----/
\ /
|
----------
| TA |
----------
是的,您有兩個Person
成員的副本( Student::y
和Faculty::y
)。
通過虛擬繼承,您擁有一顆鑽石,只有一個獨特的Person
。
不要打印整數參數,而是嘗試打印成員變量的地址。 然后嘗試使用虛擬繼承,它應該可以更好地了解發生了什么。
std::cout << &y << std::endl;
嘗試調查您實例化的 TA 對象的大小。 尺碼告訴你什么? 對於 Person 的單個副本,您期望多大的尺寸? 兩份嗎?
嘗試實際訪問 y 屬性,看看是否出現編譯器錯誤!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.