seo做论坛和企业网站差别,凡科网站怎么做,品牌网站建设gs,肇庆新闻头条 今天加qq1126137994 微信#xff1a;liu1126137994
C中是否允许一个类继承多个父类#xff1f;
C支持编写多重继承的代码#xff1a;
一个子类可以拥有多个父类子类拥有所有父类的成员变量子类继承父类所有的成员函数子类对象可以当做任意父类对象使用
多重继承的语法规则liu1126137994
C中是否允许一个类继承多个父类
C支持编写多重继承的代码
一个子类可以拥有多个父类子类拥有所有父类的成员变量子类继承父类所有的成员函数子类对象可以当做任意父类对象使用
多重继承的语法规则
多重继承的本质与单继承相同
编程示例;
#include iostream
#include stringusing namespace std;class BaseA
{int ma;
public:BaseA(int a){ma a;}int getA(){return ma;}
};class BaseB
{int mb;
public:BaseB(int b){mb b;}int getB(){return mb;}
};class Derived : public BaseA, public BaseB
{int mc;
public:Derived(int a, int b, int c) : BaseA(a), BaseB(b){mc c;}int getC(){return mc;}void print(){cout ma getA() , mb getB() , mc mc endl;}
};int main()
{cout sizeof(Derived) sizeof(Derived) endl; // 12Derived d(1, 2, 3);d.print();cout d.getA() d.getA() endl;cout d.getB() d.getB() endl;cout d.getC() d.getC() endl;cout endl;BaseA* pa d;BaseB* pb d;cout pa-getA() pa-getA() endl;cout pb-getB() pb-getB() endl;cout endl;void* paa pa;void* pbb pb;if( paa pbb ){cout Pointer to the same object! endl; }else{cout Error endl;}cout pa pa endl;cout pb pb endl;cout paa paa endl;cout pbb pbb endl; return 0;
}运行结果
分析以上程序我们就可以发现问题所在啦 1、通过多重继承的对象可能拥有不同的地址 2、多重继承可能产生冗余的成员 当多重继承关系闭合将产生数据冗余问题 解决办法是 虚继承
下面看一个解决冗余的例子
#include iostream
#include stringusing namespace std;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 : virtual public People
{
public:Teacher(string name, int age) : People(name, age){}
};class Student : virtual 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(Delphi, 33);d.print();return 0;
}运行结果为; Name Delphi, Age 33
虚继承能够解决数据冗余的问题中间层父类不再关心顶层父类的初始化最终子类必须直接调用顶层父类的构造函数
虽然我们解决的数据冗余但是还有一个问题在架构设计师无法确定使用虚继承还是直接继承
3、多重继承有可能会产生多个虚函数表
#include iostream
#include stringusing namespace std;class BaseA
{
public:virtual void funcA(){cout BaseA::funcA() endl;}
};class BaseB
{
public:virtual void funcB(){cout BaseB::funcB() endl;}
};class Derived : public BaseA, public BaseB
{};int main()
{Derived d;BaseA* pa d;BaseB* pb d;BaseB* pbe (BaseB*)pa; // oops!!BaseB* pbc dynamic_castBaseB*(pa); //dynamic_cast会对指针进行修正cout sizeof(d) sizeof(d) endl;cout Using pa to call funcA()... endl;pa-funcA();cout Using pb to call funcB()... endl;pb-funcB();cout Using pbc to call funcB()... endl;pbc-funcB();cout endl;cout pa pa endl;cout pb pb endl;cout pbe pbe endl;cout pbc pbc endl;return 0;
}工程开发中的多继承方式
#include iostream
#include stringusing namespace std;class Base
{
protected:int mi;
public:Base(int i){mi i;}int getI(){return mi;}bool equal(Base* obj){return (this obj);}
};class Interface1
{
public:virtual void add(int i) 0;virtual void minus(int i) 0;
};class Interface2
{
public:virtual void multiply(int i) 0;virtual void divide(int i) 0;
};class Derived : public Base, public Interface1, public Interface2
{
public:Derived(int i) : Base(i){}void add(int i){mi i;}void minus(int i){mi - i;}void multiply(int i){mi * i;}void divide(int i){if( i ! 0 ){mi / i;}}
};int main()
{Derived d(100);Derived* p d;Interface1* pInt1 d;Interface2* pInt2 d;cout p-getI() p-getI() endl; // 100pInt1-add(10);pInt2-divide(11);pInt1-minus(5);pInt2-multiply(8);cout p-getI() p-getI() endl; // 40cout endl;cout pInt1 p : p-equal(dynamic_castBase*(pInt1)) endl;cout pInt2 p : p-equal(dynamic_castBase*(pInt2)) endl;return 0;
}运行结果
p-getI() 100 p-getI() 40
pInt1 p : 1 pInt2 p : 1
一些有用的工程建议
先继承自一个父类然后实现多个接口父类中提供equal()成员函数equal()成员函数用于判断当前指针是否指向当前对象与多重继承相关的强制类型转换用dynamic_cast完成
总结
多继承中可能出现多个虚函数表指针与多重继承相关的强制类型转换用dynamic_cast完成工程开发中使用单继承多接口的方式实现多继承父类提供成员函数用来判断指针是否指向当前对象