简体   繁体   English

为什么派生类可以调用基类构造函数两次?

[英]Why can a derived class call base class constructor twice?

I am learning about multiple inheritance and the diamond problem, but I'm confused as to why a base class constructor can be called twice without a compiler error in the first place.我正在学习多重继承和菱形问题,但我很困惑为什么基类构造函数可以被调用两次而不会首先出现编译器错误。

Example from https://www.geeksforgeeks.org/multiple-inheritance-in-c/示例来自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); 
} 

Output:输出:

Person::Person(int ) called
Faculty::Faculty(int ) called
Person::Person(int ) called
Student::Student(int ) called
TA::TA(int ) called

Since the derived class TA calls the Person constructor twice, doesn't that mean TA would have two copies of data members that have the same name, for example two instances of int y ?由于派生类TA两次调用Person构造函数,这是否意味着TA会有两个同名数据成员的副本,例如int y两个实例?

Drawing from link is misleading, it is not a diamond, but more a Y:从链接中提取是误导性的,它不是菱形,而是 Y:

 ----------    ----------
|  Person  |  |  Person  |
 ----------    ----------
      ^             ^
      |             |
 ----------    ----------
|  Student |  |  Faculty |
 ----------    ----------
      ^             ^
      |             |
       \-----   ----/
             \ /
              |
         ----------
        |    TA    |
         ----------

And yes you have two copies of member of Person ( Student::y and Faculty::y ).是的,您有两个Person成员的副本( Student::yFaculty::y )。

With virtual inheritance, you have a diamond with only one unique Person .通过虚拟继承,您拥有一颗钻石,只有一个独特的Person

Instead of printing the integer argument, try printing the address of the member variable instead.不要打印整数参数,而是尝试打印成员变量的地址。 Then try it with virtual inheritance, it should give a better idea what's going on.然后尝试使用虚拟继承,它应该可以更好地了解发生了什么。

std::cout << &y << std::endl;

Try investigating the size of the TA object you instantiate.尝试调查您实例化的 TA 对象的大小。 What does the size tell you?尺码告诉你什么? What size would you expect for the case of a single copy of Person?对于 Person 的单个副本,您期望多大的尺寸? For two copies?两份吗?

Try actually accessing the y attribute and see if you get a compiler error!尝试实际访问 y 属性,看看是否出现编译器错误!

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

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