多继承:一个类有多个直接基类的继承关系称为多继承
总结:
1、一般将具有菱形样式继承方式的某些类声明为虚继承
3、虚继承的主要目的是为了防止二义性
2、虚继承就是在继承方式前加virtual
如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性
如:
虚继承virtual
如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性
如果在多条继承路径上有一个公共的基类,那么在继承路径的某处 汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象 要使这个公共基类在派生类中只产生一个子对象,必须对这个基类声明为虚继承,使这个基类成为虚基类。
虚继承声明使用关键字 virtual
多继承:
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;#if 0
//多继承案例
//家具类
class Furniture
{
};//将父亲类继承爷爷类 改成虚继承, 防止儿子在多继承我的时候,出现爷爷中的变量会拷贝多份。
class Bed :public Furniture
{
public:void sleep() {cout << "在床上睡觉" << endl;}
};class Sofa :public Furniture
{
public:void sit() {cout << "在沙发上休息" << endl;}
};//沙发床
class SofaBed :public Bed, public Sofa
{
public:void SleepAndSit() {sleep();sit();}
};
void test01() {Bed b;b.sleep();Sofa s;s.sit();cout << " ------ " << endl;SofaBed sb;sb.SleepAndSit();
}
#endif//家具类
class Furniture
{
public:int m; //材质Furniture() {m = 0;}
};//将父亲类继承爷爷类 改成虚继承, 防止儿子在多继承我的时候,出现爷爷中的变量会拷贝多份。
class Bed :virtual public Furniture
{
public:Bed() {m = 1;}void sleep() {cout << "在床上睡觉" << endl;}
};class Sofa :virtual public Furniture
{
public:Sofa() {m = 2;}void sit() {cout << "在沙发上休息" << endl;}
};//沙发床
class SofaBed :public Sofa,public Bed
{
public:SofaBed() {//m = 3;}void SleepAndSit() {sleep();sit();}
};void test01() {SofaBed s;cout<<s.m<<endl; //将父亲的继承方式改为虚继承。这样在s中就只有一个爷爷中的数据成员//否则在s中分别有从Bed和Sofa中继承的m,s去访问 会有指向不明确的说法//情况1:当SofaBed的构造函数中m=3时,s.m=3//情况2:当SofaBed的继承方式为public Sofa,public Bed时, s.m=1//情况3:当SofaBed的继承方式为public Bed,public Sofa时,s.m=2//当前继承情况下:cout << s.Furniture::m << endl;//1cout << s.Bed::m<<endl; //1cout << s.Sofa::m<<endl;//1}
int main(void)
{test01();return 0;
}
#endif
虚继承:
#if 1
#include<iostream>
using namespace std;
class GrandPa {
public:int m;GrandPa() {cout << "GrandPa()" << endl;}
};
class Parent1 :public GrandPa {
public:Parent1() {cout << "Parent1()" << endl;}};
class Parent2 :public GrandPa {
public:Parent2() {cout << "Parent2" << endl;}
};
class Son :public Parent1, public Parent2 {
public:Son() {cout << "Son()" << endl;}
};
void test01() {Son s;
}
/*
GrandPa()
Parent1()
GrandPa()
Parent2
Son()
*/
void test02() {Son s;//s.m; //直接访问编译错误 不明确 此时的m是Parent1还是Parent2还是Grandpacout<<s.Parent1::m<<endl;cout<<s.Parent2::m<<endl;cout<<s.GrandPa::m<<endl;
}
/*
GrandPa()
Parent1()
GrandPa()
Parent2
Son()
-858993460
-858993460
-858993460
*/
int main() {//test01();test02();return 0;
}
#endif