问题:
C++中是否允许一个类继承自多个父类?
这就是多重继承。
多重继承问题1:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class BaseA 7 { 8 int ma; 9 public: 10 BaseA(int a) 11 { 12 ma = a; 13 } 14 int getA() 15 { 16 return ma; 17 } 18 }; 19 20 class BaseB 21 { 22 int mb; 23 public: 24 BaseB(int b) 25 { 26 mb = b; 27 } 28 int getB() 29 { 30 return mb; 31 } 32 }; 33 34 class Derived : public BaseA, public BaseB 35 { 36 int mc; 37 public: 38 Derived(int a, int b, int c) : BaseA(a), BaseB(b) 39 { 40 mc = c; 41 } 42 int getC() 43 { 44 return mc; 45 } 46 void print() 47 { 48 cout << "ma = " << getA() << ", " 49 << "mb = " << getB() << ", " 50 << "mc = " << mc << endl; 51 } 52 }; 53 54 int main() 55 { 56 cout << "sizeof(Derived) = " << sizeof(Derived) << endl; // 12 57 58 Derived d(1, 2, 3); 59 60 d.print(); 61 62 cout << "d.getA() = " << d.getA() << endl; 63 cout << "d.getB() = " << d.getB() << endl; 64 cout << "d.getC() = " << d.getC() << endl; 65 66 cout << endl; 67 68 BaseA* pa = &d; 69 BaseB* pb = &d; 70 71 cout << "pa->getA() = " << pa->getA() << endl; 72 cout << "pb->getB() = " << pb->getB() << endl; 73 74 cout << endl; 75 76 void* paa = pa; 77 void* pbb = pb; 78 79 80 if( paa == pbb ) 81 { 82 cout << "Pointer to the same object!" << endl; 83 } 84 else 85 { 86 cout << "Error" << endl; 87 } 88 89 cout << "pa = " << pa << endl; 90 cout << "pb = " << pb << endl; 91 cout << "paa = " << paa << endl; 92 cout << "pbb = " << pbb << endl; 93 94 return 0; 95 }
结果如下:
pa和pb地址是不一样的,这就是多重继承的问题。
分析:
两个指针地址值不一样时,它们也有可能指向的是同一个对象,这就是多重继承引入的问题。
多重继承的问题2:
示例程序:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class People 7 { 8 string m_name; 9 int m_age; 10 public: 11 People(string name, int age) 12 { 13 m_name = name; 14 m_age = age; 15 } 16 void print() 17 { 18 cout << "Name = " << m_name << ", " 19 << "Age = " << m_age << endl; 20 } 21 }; 22 23 class Teacher : virtual public People 24 { 25 public: 26 Teacher(string name, int age) : People(name, age) 27 { 28 } 29 }; 30 31 class Student : virtual public People 32 { 33 public: 34 Student(string name, int age) : People(name, age) 35 { 36 } 37 }; 38 39 class Doctor : public Teacher, public Student 40 { 41 public: 42 Doctor(string name, int age) : Teacher(name, age), Student(name, age), People(name, age) 43 { 44 } 45 }; 46 47 int main() 48 { 49 Doctor d("Delphi", 33); 50 51 d.print(); 52 53 return 0; 54 }
虚继承就不会调用父类的构造函数了。
虚继承情况下Docter类需要直接调用顶层父类的构造函数,如第42行所示。
在大型的工程中,我们可能很难找到顶层父类,虚继承解决了数据冗余问题,但是带来了项目管理问题。
运行结果如下:
多重继承给架构设计带来了问题,因为我们不知道开发者会不会使用多重继承,因此我们设计架构时,无法确定使用直接继承还是虚继承。我们把所有的继承都写成虚继承可以解决这个问题,但是带来了效率问题。不同的编译器也可能产生不同的效果。
工程项目中不要使用多重继承。
小结: