多重继承

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



一个简单的Webmail系统

一个简单的Webmail系统      来源:sadly      这是一段Web Mail的示范代码,功能不是很强,但是结构还比较完整,主要的功能如查看文件夹,查看信件,回复,写信都有。但是程序中没...
  • peacock
  • peacock
  • 2000-12-19 02:25:00
  • 725

多重继承的内存分配

VC++,掀起你的盖头来 ——谈VC++对象模型 (美)简  格雷 程化    译 译者前言 一个C++程序员,想要进一步提升技术水平的话,应该多了解一些语言的语意细节。对于使用V...
  • maowenge
  • maowenge
  • 2015-05-04 11:19:40
  • 887

一个c++多重继承的例子

/*一个多重继承的例子,以下的所有函数均直接写在类中*/ #include #include using namespace std; /*定义Hdd类表示硬盘*/ class Hdd { pr...
  • xiongyangg
  • xiongyangg
  • 2014-04-27 16:31:36
  • 1896

python 多重继承的方法解析顺序

任何实现多重继承的语言都要处理潜在的命名冲突, 这种冲突由不相关的祖先类实现同名方法引起 class A: def say(self): print("A Hello:",...
  • u011019726
  • u011019726
  • 2017-08-30 11:22:55
  • 1721

C++ 虚函数表研究 (二) 多重继承

C++ 虚函数表研究 (二) 多重继承
  • tangaowen
  • tangaowen
  • 2010-08-22 23:26:00
  • 5939

java为什么不允许多重继承

张三和李四一同到一家公司去应聘,二人被安排同时接受经理的面试。 经理拿出一个代码片段: public class Father { public void makeMoney(){ ...
  • ndlgyb1
  • ndlgyb1
  • 2016-08-17 13:58:37
  • 1725

C#学习日记22---多重继承

继承是面向对象程序设计中最重要的概念之一。继承允许我们根据一个类来定义另一个类来定义一个类,一个类从另一个类派生出来时,派生类从基类那里继承特性          继承的思想实现了 属于(IS-A)...
  • HC666
  • HC666
  • 2015-10-12 18:44:51
  • 1918

详谈C++虚函数表那回事(多重继承关系)

C++多重继承关系中虚函数表相关
  • Li_Ning_
  • Li_Ning_
  • 2016-07-13 00:51:54
  • 1682

C++多重继承的指针问题

下面说说C++多重继承中关于指针的一些问题。指针指向问题 先看下面的程序:class Base1 { public: virtual void fun1() {cout ...
  • T_27080901
  • T_27080901
  • 2015-05-17 21:04:23
  • 1143

多重继承的特点、作用/意义和使用条件

多重继承的特点、意义和使用条件 多重继承MI:Multiple Inheritance;单一继承:Single Inheritance; C++阵营中有两派:一种是认为多重继承不好用,一种认为多重...
  • realDonaldTrump
  • realDonaldTrump
  • 2017-10-20 15:00:28
  • 408
收藏助手
不良信息举报
您举报文章:多重继承
举报原因:
原因补充:

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