多重继承

一. 子对象重叠问题

1. 当继承基类时,在派生类中就得到了基类所有数据成员的副本,该副本称为子对象,如果存在菱形继承,就会出现子对象重叠的情况:

                                                        


2. 向上二义性

当new mi,并将其传给base*时,由于没办法搞清楚打算使用d1子对象的base还是d2子对象的base作为结果地址,所以编译器将不会受理,如下:

#include <iostream>
#include "Tstash.h"
using namespace std;

class base
{
public:
	virtual char* vf() const = 0;
};

class d1 : public base
{
public:
	char* vf() const
	{
		return "d1";
	}
};

class d2 : public base
{
public:
	char* vf() const
	{
		return "d2";
	}
};

class mi : public d1, public d2{}; //问题1:cause error: ambiguous override of vf()

int main()
{
	tstash<base> b;
	b.add(new d1);
	b.add(new d2);
	b.add(new mi); //问题2:error C2594: 'argument' : ambiguous conversions from 'mi *' to 'base *'

	for(int i = 0; i < b.count(); i++)
	{
		cout << b[i]->vf() << endl;
	}

	system("pause");
	return 1;
}
对于问题1,必须对类mi中的函数vf进行重新定义,以消除二义性

对于问题2,着眼于语言层面的扩展,可以进行virtual继承,例如:

#include <iostream>
#include "Tstash.h"
using namespace std;

class base
{
public:
	virtual char* vf() const = 0;
};

class d1 : virtual public base
{
public:
	char* vf() const
	{
		return "d1";
	}
};

class d2 : virtual public base
{
public:
	char* vf() const
	{
		return "d2";
	}
};

class mi : public d1, public d2
{
public:
	char* vf() const
	{
		return d1::vf();
	}
};

int main()
{
	tstash<base> b(no);
	b.add(new d1);
	b.add(new d2);
	b.add(new mi);
	for (int i = 0; i < b.count(); i++)
	{
		cout << b[i]->vf() << endl;
	}

	system("pause");
	return 1;
}

二. “最晚派生”类和虚基类初始化

所谓“最晚派生类”是指当前所在类,例如:基类构造函数里最晚派生类是base;在d1构造函数里,d1是最晚派生类;在mi构造函数里,mi是最晚派生类。打算使用虚基类时,最晚派生类构造函数的职责是对虚基类进行初始化,这意味着不管该类离虚基类多远,都有责任对虚基类进行初始化,例如:


//virtual base initialization
//virtual base classes must always be initialized by the "most-derived" class
#include <iostream>
#include "Tstash.h"
using namespace std;

class base
{
public:
	base(int){}
	virtual char* vf() const = 0;
};

class d1 : virtual public base
{
public:
	d1() : base(1){}
	char* vf() const{return "d1";}
};

class d2 : virtual public base
{
public:
	d2() : base(2){}
	char* vf() const{return "d2";}
};

class mi : public d1, public d2
{
public:
	mi() : base(3){}
	char* vf() const
	{
		return d1::vf();
	}
};

class x : public mi
{
public:
	x() : base(4){}
};

int main()
{
	tstash<base> b(no);
	b.add(new d1);
	b.add(new d2);
	b.add(new mi);
	b.add(new x);
	for (int i = 0; i < b.count(); i++)
	{
		cout << b[i]->vf() << endl;
	}

	system("pause");
	return 1;
}

每个子类都要对虚基类进行初始化,这样比较麻烦,可以给虚基类使用缺省构造函数,比如:

#include <iostream>
#include "Tstash.h"
using namespace std;

class base
{
public:
	base(int = 0){}
	virtual char* vf() const = 0;
};

class d1 : virtual public base
{
public:
	d1() : base(1){}
	char* vf() const { return "d1"; }
};

class d2 : virtual public base
{
public:
	d2() : base(2){}
	char* vf() const{return "d2";}
};

class mi : public d1, public d2
{
public:
	mi(){}
	char* vf() const
	{
		return d1::vf();
	}
};

class x : public mi
{
public:
	x(){}
};

int main()
{
	tstash<base> b;
	b.add(new d1);
	b.add(new d2);
	b.add(new mi);
	b.add(new x);
	for(int i = 0; i < b.count(); i++)
	{
		cout << b[i]->vf() << endl;
	}

	system("pause");
	return 1;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值