多重继承和虚继承

        这两个技术一般只会在大的项目才会遇到。在多重继承中,派生类对它的每一个基类的成员都会保留一份,在复杂的面向对象建模中,派生类可能直接或间接地继承同一个基类多次,如果不做特别说明的话,派生类就会保留多份这个基类的成员,为防止这种情况的出现,需要将继承同一个基类时候的继承动作声明为虚继承,而这个被多次继承的基类称为虚基类。这里通过一些简单的例子,加以说明:

    一、多重继承

#include<iostream>
using namespace std;
class Base1{
public:
	Base1(){
		cout<<"constru Base1"<<endl;
	}
	virtual void print(){
		cout<<"Base1"<<endl;
	}
	virtual ~Base1(){
		cout<<"del Base1"<<endl;
	}
};
class Base2{
public:
	Base2(){
		cout<<"constru Base2"<<endl;
	}
	virtual void print(){
		cout<<"Base2"<<endl;
	}
	virtual ~Base2(){
		cout<<"del Base2"<<endl;
	}
};
class D1:public Base1{
public:
	D1(){
		cout<<"constru D1"<<endl;
	}
	virtual void print(){
		cout<<"D1"<<endl;
	}
	virtual ~D1(){
		cout<<"del D1"<<endl;
	}
};
class D2:public Base2{
public:
	D2(){
		cout<<"constru D2"<<endl;
	}
	virtual void print(int i){
		cout<<"D2"<<endl;
	}
	virtual ~D2(){
		cout<<"del D2"<<endl;
	}
};
class MI:public D1,public D2{
public:
	MI(){
		cout<<"constru MI"<<endl;
	}
	virtual void print(){
		cout<<"MI"<<endl;
	}
	virtual ~MI(){
		cout<<"del MI"<<endl;
	}
};
int main(){
	MI mi;
	mi.Base1::print(); //如果MI中没有重新定义print函数的话,这里对print的调用会出现二义性,因为
                       //MI的直接基类D1和D2中都定义了print函数,即使参数不同,但名字查找先与类型检查
                       //而且这种查找会在MI的两个继承分支中并行进行,只要在两个分支中都找到print,就
                       //出现二义性错误,不管在继承体系中出现的层次深浅如何。 
        system("pause");
	Base1 *pb1=new MI;
	cout<<"*************"<<endl;
	Base2 *pb2=new MI;
	cout<<"*************"<<endl;
	D1 *pd1=new MI;
	cout<<"*************"<<endl;
	D2 *pd2=new MI;
	cout<<"*************"<<endl;

	pb1->print();
	pd1->print();
	pd2->print();
	cout<<"*************"<<endl;
	delete pb2;
	cout<<"*************"<<endl;
	delete pd1;
	cout<<"*************"<<endl;
	delete pd2;

	system("pause");
}       
       通过观察上面程序的运行结果可以发现:在多重继承体系中,对象的析构顺序与构造顺序也是正好相反的,并且多个基类的构造顺序由派生列表中基类出现的顺序决定,而与初始化列表中的构造顺序无关(上面的程序没有给出初始化列表)。

二、虚继承

#include<iostream>
using namespace std;
class B{
public:
	void print(){
		cout<<"B"<<endl;
	}
};
class D1:public virtual B{
};
class D2:public virtual B{
};
class MI:public D1,public D2{
	
};
int main(){
	MI mi;
	mi.print();
	system("pause");
}
两处的virtual关键字 缺一不可,不然mi.print()语句将报错:对print的调用出现二义性。因为MI继承了B的两份成员。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值