问题引出:在C++中是否允许一个类继承自多个类?在C#和java语言中,是不能多重继承的
何为多重继承呢,简单的说,多重继承就是子类有多个父类,子类继承所有父类的成员函数与成员变量,子类对象可以当做任意父类对象
使用
1.C++中的多重继承
语法规则:
2.编程实验-多重继承问题一
#include <iostream>
using 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 BaseC
{
int mc;
public:
BaseC(int c)
{
mc = c;;
}
int GetC()
{
return mc;
}
};
class Derived:public BaseA,public BaseB,public BaseC
{
int md;
public:
Derived(int a,int b,int c,int d):BaseA(a),BaseB(b),BaseC(c)
{
md = d;
}
int GetD()
{
return md;
}
void print()
{
cout << "ma = "<<GetA()<<","
"mb = "<<GetB()<<","
"mc = "<<GetC()<<","
"md= "<<md<<","<<endl;
}
};
int main()
{
Derived d(1,2,3,4);
cout <<"d.GetA()"<<d.GetA()<<endl;
cout <<"d.GetB()"<<d.GetB()<<endl;
cout <<"d.GetC()"<<d.GetC()<<endl;
cout <<"d.GetD()"<<d.GetD()<<endl;
BaseA *pa = &d;//父类指针指向子类对象
BaseB *pb = &d;//父类指针指向子类对象
cout <<"pa->getA()"<<pa->GetA()<<endl;
cout <<"pb->getB()"<<pb->GetB()<<endl;
void * paa = pa;
void * pbb = pb;
if(paa == pbb)
{
cout << "pointer is the same object"<<endl;
}else
{
cout << "error"<<endl;
}
cout << "pa"<<pa<<endl;
cout << "pb"<<pb<<endl;
cout << "paa"<<paa<<endl;
cout << "pbb"<<pbb<<endl;
d.print();
return 0;
}
结果:
从从结果看出pa与pb的地址不一样,意味着多重继承得到的对象可能拥有不同的地址,这其实是多重继承存在的一个问题,还未有解决方案
3.多重继承的问题二
- 多重继承可能产生冗余的成员
#include <iostream>
#include <string>
using 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 << "m_name = "<<m_name<<","
<< "m_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 + "1",age+1),Student(name+"2",age+2)
{
}
};
int main()
{
Doctor d("Delphi",33);
//d.print();会产生二义性
d.Teacher::print();
d.Student::print();
}
结果:
结果可以看出来,当多重关系出现闭合时,会产生数据冗余问题!!!那么改如何解决这个问题呢,解决方案为虚继承
- 虚继承能够解决数据冗余问题
- 中间层父类不再关系顶层父类的初始化
- 最终子类必须
直接调用顶层父类的构造函数
#include <iostream>
#include <string>
using 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 << "m_name = "<<m_name<<","
<< "m_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 + "1",age+1),Student(name+"2",age+2),People(name,age)
{
}
};
int main()
{
Doctor d("Delphi",33);
//d.print();会产生二义性
//d.Teacher::print();
//d.Student::print();
d.print();
}
从结果可以看出,进行虚继承后,子类直接调用顶层父类的构造函数
问题:当架构中需要继承时,无法确定直接继承还是虚继承
解决:多继承只适合于学术,不适合实际的工程开发
4.小结
- 只有c++支持多重继承的编程方式
- 多重继承容易带来问题
- 可能出现
同一个对象地址不同的情况
- 虚继承可以解决数据冗余的问题
- 虚继承使得架构设计可能出现问题
- 可能出现