多重继承

翻译 2013年12月05日 13:32:49

一. 子对象重叠问题

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



C++习题 多重继承

  • 2016年07月07日 12:59
  • 5KB
  • 下载

java提高篇(八)-----实现多重继承

多重继承指的是一个类可以同时从多于一个的父类那里继承行为和特征,然而我们知道Java为了保证数据安全,它只允许单继承。有些时候我们会认为如果系统中需要使用多重继承往往都是糟糕的设计,这个时候我们往往需...
  • chenssy
  • chenssy
  • 2013年10月27日 11:00
  • 13594

多重继承相关

  • 2012年03月20日 14:31
  • 122KB
  • 下载

(转)多重继承下的虚函数表

  • 2011年05月05日 15:42
  • 133KB
  • 下载

Bug现形记(一):一个多重继承程序的查错

【课程支撑】我的 C++程序设计课程教学材料  要完成的任务详见第12周-任务2-双肩挑干部。题目要求  分别定义Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类T...

实现c++类的多重继承的例程

  • 2011年04月25日 09:09
  • 848KB
  • 下载

实现C++类的多重继承

  • 2017年11月11日 15:12
  • 4.13MB
  • 下载

多重继承下,不同基类指针指向同一子类对象的地址问题——腾讯一笔试题

多重继承下,不同基类指针指向同一子类对象的地址问题——腾讯一笔试题   2 原文:http://www.haogongju.net/art/1694028 多继承时,父类...
  • dalleny
  • dalleny
  • 2014年08月18日 14:35
  • 1748

C++多重继承

  • 2012年10月30日 20:52
  • 257KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多重继承
举报原因:
原因补充:

(最多只允许输入30个字)