关闭

多重继承

246人阅读 评论(0) 收藏 举报
分类:

一. 子对象重叠问题

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;
}



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:7780次
    • 积分:287
    • 等级:
    • 排名:千里之外
    • 原创:4篇
    • 转载:2篇
    • 译文:17篇
    • 评论:0条
    文章分类