多继承“
一个类有多个直接基类的继承关系称为多继承
多继承声明语法
class 派生类名 : 访问控制 基类名1 , 访问控制 基类名2 , … , 访问控制 基类名n
{
数据成员和成员函数声明
};
多个基类的派生类构造函数可以用初始式调用基类构造函数初始化数据成员。
执行顺序与单继承构造函数情况类似。多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。
一个派生类对象拥有多个直接或间接基类的成员。不同名成员访问不会出现二义性。如果不同的基类有同名成员,派生类对象访问时应该加以识别。
多继承的简单应用
1 class Base1 2 { public: 3 Base1(int x) { value = x ; } 4 int getData() const { return value ; } 5 protected: 6 int value; 7 }; 8 class Base2 9 { public: 10 Base2(char c) { letter=c; } 11 char getData() const { return letter;} 12 protected: 13 char letter; 14 }; 15 class Derived : public Base1, public Base2 16 { friend ostream &operator<< ( ostream &, const Derived & ) ; 17 public : 18 Derived ( int, char, double ) ; 19 double getReal() const ; 20 private : 21 double real ; 22 };
2.虚基类
如果一个派生类从多个基类派生,而这些基类又有一个共同
的基类,则在对该基类中声明的名字进行访问时,可能产生
二义性。
例如:
1 class B { public : int b ;} ; 2 3 class B1 : public B { private : int b1 ; } ; 4 5 class B2 : public B { private : int b2 ; } ; 6 7 class C : public B1 , public B2 8 9 { public : int f ( ) ; private : int d ; } ; 10 11 12 13 /*C c ; 14 15 c . B ; // error 16 17 c . B :: b ; // error,从哪里继承的? 18 19 c . B1 :: b ; // ok,从B1继承的 20 21 c . B2 :: b ; // ok ,从B2继承的*/ 22 23 24 25 #include<iostream> 26 27 using namespace std ; 28 29 int main () 30 31 { C c ; 32 33 c . B1 :: b = 5 ; c . B2 :: b = 10 ; 34 35 cout << "path B1==> " << c . B1 :: b << endl ; 36 37 cout << "path B2==> " << c . B2 :: b << endl ; 38 39 }
建立 C 类的对象时,B 的构造函数将被调用两次:一次由B1调用,另一次由 B2 调用,以初始化 C 类的对象中所包含的两个 B 类的子对象
如果在多条继承路径上有一个公共的基类,那么在继承路径的某处
汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象。
要使这个公共基类在派生类中只产生一个子对象,必须对这个基类
声明为虚继承,使这个基类成为虚基类。
虚继承声明使用关键字 virtual
1 #include <iostream> 2 using namespace std; 3 4 //虚基类的测试 5 class A 6 { 7 public: 8 A(){ cout << "class a\n"; } 9 }; 10 11 //如果在此处不加上virtual关键字则会调用两次A类的构造函数 12 class B1:virtual public A 13 { 14 public: 15 B1(){ cout << "class b1\n"; } 16 }; 17 //如果在此处不加上virtual关键字则会调用两次A类的构造函数 18 class B2:virtual public A 19 { 20 public: 21 B2(){ cout << "class b2\n";} 22 }; 23 class C:public B1,public B2 24 { 25 public: 26 C(){ cout << "class C\n"; } 27 }; 28 void main() 29 { 30 C c; 31 }
继承是面向对象程序设计实现软件重用的重要方法。程序员可以在已有基类的基础上定义新的派生类。
单继承的派生类只有一个基类。多继承的派生类有多个基类。
派生类对基类成员的访问由继承方式和成员性质决定。
创建派生类对象时,先调用基类构造函数初始化派生类中的基类成员。调用析构函数的次序和调用构造函数的次序相反。
C++提供虚继承机制,防止类继承关系中成员访问的二义性。
多继承提供了软件重用的强大功能,也增加了程序的复杂性。