问题:
C++ 中是否允许一个类继承多个父类?
C++支持编写多重继承的代码
- 一个子类可以拥有多个父类
- 子类拥有所有父类的成员变量
- 子类继承所有父类的成员函数
- 子类对象可以当作任意父类对象使用
多重语法规则
class Derived : public BaseA, public BaseB, public BaseC
{
};
多重继承的本质与单继承相同
示例:
class CBaseA
{
int m_a;
public:
CBaseA(int a)
{
m_a = a;
}
int getA()
{
return m_a;
}
};
class CBaseB
{
int m_b;
public:
CBaseB(int b)
{
m_b = b;
}
int getB()
{
return m_b;
}
};
class CDerived : public CBaseA, public CBaseB
{
int m_c;
public:
CDerived(int a, int b, int c): CBaseA(a), CBaseB(b)
{
m_c = c;
}
void print()
{
cout << "ma = " << getA() << ", "
<< "mb = " << getB() << ", "
<< "mc = " << m_c << endl;
}
};
int main()
{
CDerived d(1, 2, 3);
d.print();
CBaseA *pa = &d;
CBaseB *pb = &d;
cout << pa->getA() << endl;
cout << pb->getB() << endl;
cout << endl;
void *paa = pa;
void *pbb = pb;
if( paa == pbb)
{
cout << " Pointer same adder " << endl;
}
else
{
cout << "Not Pointer same adder " << endl;
}
cout << "pa = " << pa << endl;
cout << "pb = " << pb << endl;
cout << "paa = " << paa << endl;
cout << "pbb = " << pbb << endl;
return 0;
}
输出:
ma = 1, mb = 2, mc = 3
1
2
Not Pointer same adder
pa = 0x7ffd70e33930
pb = 0x7ffd70e33934
paa = 0x7ffd70e33930
pbb = 0x7ffd70e33934
分析:父类指针指向同一个同一个子类,但是地址却不一样
多重继承的问题一
通过多重继承得到的对象可以拥有 不同的地址(没有对应的解决方案)
Derived d(1, 2, 3);
BaseA* pa = &d;
BaseB* pb = &d;
指向相同的对象,但是对象的地址却不一样,好比一个指向头,一个指向胸口
多重继承的问题二
多重继承可能产生冗余的成员
class People
{
string m_name;
int m_age;
public:
People(string name, int age)
{
m_name = name;
m_age = age;
}
void print()
{
cout << "Name = " << m_name << ", "
<< "Age = " << m_age << endl;
}
};
class Teacher : public People
{
public:
Teacher(string name, int age) : People(name, age)
{
}
};
class Student : public People
{
public:
Student(string name, int age) : People(name, age)
{
}
};
class Doctor : public Teacher, public Student
{
public:
Doctor(string name, int age) : Teacher(name, age), Student(name, age), People(name, age)
{
}
};
int main()
{
Doctor d("Kevin", 24);
d.print();
return 0;
}
错误信息:
Test.cpp:144:7: error: request for member ‘print’ is ambiguous
d.print();
当多重继承关系出现闭合时将参生数据冗余的问题
- 解决方法:虚继承
class People {};
class Teacher : virtual public People {};
class Student : virtual public People {};
class Doctor : public Teacher, public Student {};
- 虚继承能够解决数据冗余问题
- 中间层父类不在关心顶层父类的初始化
- 最终子类必须直接调用顶层父类的构造函数
目前来看只有C++语言支持多继承
问题:
当架构设计中需要继承时,无法确认使用直接继承还是虚继承!
虚继承在项目管理上带来了难度,多继承不适合实际的项目开发。
小结
- C++支持多重继承的编程方式
- 多重继承容易带来的问题
- 可能出现同一个对象的地址不同的情况
- 虚继承可以解决数据冗余问题,虚继承的使架构设计可能出现问题