如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性
分析:
总结:
- 如果一个派生类从多个基类派生,而这些基类又有一个共同
的基类,则在对该基类中声明的名字进行访问时,可能产生
二义性
- 如果在多条继承路径上有一个公共的基类,那么在继承路径的某处
汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象
- 要使这个公共基类在派生类中只产生一个子对象,必须对这个基类
声明为虚继承,使这个基类成为虚基类。
- 虚继承声明使用关键字 virtual
实验:注意增加virtual关键字后,构造函数调用的次数。
3.5继承总结
- 继承是面向对象程序设计实现软件重用的重要方法。程序员可以在已有基类的基础上定义新的派生类。
- 单继承的派生类只有一个基类。多继承的派生类有多个基类。
- 派生类对基类成员的访问由继承方式和成员性质决定。
- 创建派生类对象时,先调用基类构造函数初始化派生类中的基类成员。调用析构函数的次序和调用构造函数的次序相反。
- C++提供虚继承机制,防止类继承关系中成员访问的二义性。
- 多继承提供了软件重用的强大功能,也增加了程序的复杂性。
伪代码如下:
#include <iostream>
using namespace std;
class B
{
public:
B()
{
cout << "B构造函数" << endl; //采用了虚继承之后,尽管有多个子类,但是只会调用一次最基类的构造函数,避免了在子类中生成多个基类的对象
}
int b;
protected:
private:
};
class B1 : virtual public B
{
public:
B1()
{
cout << "B1构造函数" << endl;
}
int b1;
};
class B2 : virtual public B
{
public:
B2()
{
cout << "B2构造函数" << endl;
}
int b2;
};
class C : public B1, public B2
{
public:
C()
{
cout << "C构造函数" << endl;
}
int c;
};
void main()
{
C c1;
c1.b1 = 100;
c1.b2 = 200;
c1.c = 300;
c1.b = 500; //继承的二义性 和 虚继承解决方案
//c1.B1::b = 500;
//c1.B2::b = 500;
cout << "hello..." << endl;
system("pause");
return;
}
/**
输出:
B构造函数
B1构造函数
B2构造函数
C构造函数
*/
3.5继承总结
- 继承是面向对象程序设计实现软件重用的重要方法。程序员可以在已有基类的基础上定义新的派生类。
- 单继承的派生类只有一个基类。多继承的派生类有多个基类。
- 派生类对基类成员的访问由继承方式和成员性质决定。
- 创建派生类对象时,先调用基类构造函数初始化派生类中的基类成员。调用析构函数的次序和调用构造函数的次序相反。
- C++提供虚继承机制,防止类继承关系中成员访问的二义性。
- 多继承提供了软件重用的强大功能,也增加了程序的复杂性。