天天看点

c++——多重继承

多重继承:

必须使用关键字public来限定每一个基类,否则默认为私有继承

多重继承示例:
1.class SingingWaiter : public Waiter, public Singer { ... }

2.如未指出公有继承
class SingingWaiter : public Waiter,Singer { ... }
//Waiter是公有继承,Singer是私有继承
           

一、多重继承示例

用worker派生出singer、waiter,再用Singer,Waiter派生出MI,SingingWaiter

c++——多重继承
#include<iostream>
#include<string>

class Worker   //一个抽象的基类
{
private:
	std::string fullname;
	long id;
public:
	Worker() : fullname("no one"), id(0L) {}
	Worker(const std::string & s,long n) : fullname(s),id(n) {}

	virtual ~Worker() = 0;
	virtual void Set();
	virtual void Show() const;	
};

class Waiter : public Worker
{
private:
	int panache;
public:
	Waiter() : Worker(),panache(0) {}
	Waiter(const std::string & s,long n, int p = 0) : Worker(s,n),panache(p) {}
	Waiter(const Worker & wk, int p = 0) : Worker(wk),panache(p) {}

	void Set();
	void Show() const;
};

class Singer : public Worker
{
protected:
	enum {other,alto,contralto,soprano,bass,baritone,tenor};
	enum {Vtypes = 7};
private:
	static char *pv[Vtypes];
	int voice;
public:
	Singer() : Worker(),voice(other) {}
	Singer(const std::string & s,long n, int v = other): Worker(s,n),voice(v) {}
	Singer(const Worker & wk,int v = other) : Worker(wk),voice(v) {}

	void Set();
	void Show() const;
};
           

上述派生后SingingWaiter将会继承持有来自Singger继承来的worker类和Waiter继承来的woker类,共两个类,很明显只需要一个worker类即可

1.虚基类

虚基类:

虚基类使得从多个类派生出的对象只继承一个基类对象。

class Singer : virtual public Worker { ... };
class Waiter : public virtual Worker { ... };
class SingingWaiter : public Singer,public Waiter { ... };
//现在,SingingWaiter对象只包含一个Worker对象的副本。准确说,Singinger和Waiter共享一个副本。
           

2.虚基类的构造函数

如果Worker是虚基类
SingingWaiter(const Worker & wk,int p = 0,int v = Singre::other) : Waiter(wk,p),Singer(wk,v) {}
//上述是非法的,因为Singer和Waiter都将调用基类Worker的构造函数.

SingingWaiter(const Worker & wk,int p = 0,int v = Singer::other) : Worker(wk),Waiter(wk,p),Singer(wk,v) {}
//上述代码将显示的调用构造函数worker(const Worker &),对于虚基类是合法的,非虚基类是非法的。
           

3.MI的方法选择

示例:

Singer和Waiter中都有display的方法,如果是单继承可以直接调用display方法,现在是多继承,若直接调用会产生二义性

法一:

void SingingWaiter::display()
{
	Singer::display();
}
           

法二:

在每个类中只定义显示当前类数据成员的方法,派生类调用基类的display方法+派生类单独show方法,可以避免二义性。 为了便于在派生类中使用,将这种继承使用的方法设置为保护数据,protected

继续阅读