【发布时间】:2016-07-05 19:27:19
【问题描述】:
我在某处阅读了以下代码,作为解决多继承情况下菱形问题的示例:
#include<iostream>
using namespace std;
class A
{
int x;
public:
A() {}
A(int i) { x = i; }
void print() { cout << x; }
};
class B: virtual public A
{
public:
B():A(10) { }
};
class C: virtual public A
{
public:
C():A(100) { }
};
int main()
{
D d;
d.print();
return 0;
}
假设类D定义如下:
class D: public B, public C
{
public:
D():B(),C(){}
};
我在打印中得到了一些垃圾值。如果类D 定义如下(A 的参数化构造函数被显式调用):
class D: public B, public C
{
public:
D():B(),C(),A(20){}
};
我得到 20 作为输出。在第一种情况下,我可以理解调用了默认的 A() 构造函数,因此作为 x 的垃圾值未设置为任何值。
但是,在第二种情况下,它并不清楚。何时调用 A(int) 的参数化构造函数?如果我理解正确,调用顺序取决于继承顺序。由于B首先被继承,B的构造函数调用优先于C。由于B继承A,A()将首先被调用。然后将调用B 的构造函数。然后将调用C 的构造函数。最后,A(int) 将被调用,因为A 的构造函数在类D 中被显式调用。如果是这种情况,那么输出对于第二种情况是合理的。但是,这与以下代码的输出相矛盾:
#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 : 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 ) called
Faculty::Faculty(int ) called
Student::Student(int ) called
TA::TA(int ) called
为什么在这种情况下Person(int) 在开头调用,而不是在最后?
【问题讨论】:
标签: c++ inheritance constructor