C++中的多重继承

多重继承是C++的一个特性,其中类可以从多个类继承。

null

继承类的构造函数按继承的顺序调用。例如,在下面的程序中,B的构造函数在A的构造函数之前被调用。

#include<iostream>
using namespace std;
class A
{
public :
A()  { cout << "A's constructor called" << endl; }
};
class B
{
public :
B()  { cout << "B's constructor called" << endl; }
};
class C: public B, public A // Note the order
{
public :
C()  { cout << "C's constructor called" << endl; }
};
int main()
{
C c;
return 0;
}


输出:

B's constructor called
A's constructor called
C's constructor called

析构函数的调用顺序与构造函数的调用顺序相反。

钻石问题 当一个类的两个超类有一个公共基类时,就会出现菱形问题。例如,在下图中,TA类获取Person类的所有属性的两个副本,这会导致歧义。

图片[1]-C++中的多重继承-yiteyi-C++库

例如,考虑下面的程序。

#include<iostream>
using namespace std;
class Person {
// Data members of person
public :
Person( int x)  { cout << "Person::Person(int ) called" << endl;   }
};
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

在上面的程序中,“Person”的构造函数被调用两次。当对象“ta1”被销毁时,“Person”的析构函数也将被调用两次。所以对象“ta1”有两个“Person”所有成员的副本,这会导致歧义。 这个问题的解决方案是“虚拟”关键字 .我们将“教员”和“学生”作为虚拟基类,以避免在“TA”类中出现“人”的两个副本。例如,考虑下面的程序。

#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)   {
cout<< "TA::TA(int ) called" << endl;
}
};
int main()  {
TA ta1(30);
}


输出:

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

在上面的程序中,“Person”的构造函数被调用一次。在上述输出中需要注意的一点是, 调用“Person”的默认构造函数 .当我们使用’virtual’关键字时,默认情况下会调用祖辈类的默认构造函数,即使父类显式调用参数化构造函数。

如何调用“Person”类的参数化构造函数? 必须在“TA”类中调用构造函数。例如,请参阅以下程序。

#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

一般来说,不允许直接调用祖父母的构造函数,必须通过父类调用。仅当使用“virtual”关键字时才允许使用。

作为练习,预测以下程序的输出。

问题1

#include<iostream>
using namespace std;
class A
{
int x;
public :
void setX( int i) {x = i;}
void print() { cout << x; }
};
class B: public A
{
public :
B()  { setX(10); }
};
class C: public A
{
public :
C()  { setX(20); }
};
class D: public B, public C {
};
int main()
{
D d;
d.print();
return 0;
}


问题2

#include<iostream>
using namespace std;
class A
{
int x;
public :
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(10) {  }
};
class D: public B, public C {
};
int main()
{
D d;
d.print();
return 0;
}


如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享