C++学习笔记--多继承

这个例子中,Worker是基类,Singer和Waiter继承Worker类,SingingWaiter同时继承Singer类和Waiter类。

If you want to use something other than the default constructor for a virtual base class, you need to invoke the appropriate base constructor explicitly.

如果你想用虚父类的构造器,你必须直接显示地调用它。

SingingWaiter(const Worker & wk, int p = 0, int v = Singer::other)

    : Worker(wk), Waiter(wk, p), Singer(wk, v) {}

Multiple Inheritance can result in ambiguous function calls. You can use the scope-resolution operator to clarify what you mean:SingingWaiter newhire("Elise Hawks", 2005, 6, soprano);

多继承可以引起混乱的函数调用,你可以使用空间运算符说明所使用父类的函数。

newhire.Singer::Show();    // use Singer version

However, a better approach is to redefine Show() for SingingWaiter and to have it specify which Show() to use.

更好的方法是在子类中重新定义Show()方法,做法父类的包装函数。

void SingingWaiter::Show()
{
    Singer::Show();

}

// workermi.h -- working classes with MI

#ifndef WORKERMI_H_
#define WORKERMI_H_
#include <string>
using namespace std;
class Worker
{
private:
	string fullname;
	long id;
protected:
	virtual void Data() const;
	virtual void Get();
public:
	Worker() : fullname("no one"), id(0L) {}
	Worker(const string & s, long n)
		: fullname(s), id(n) {}
	virtual ~Worker() = 0;
	virtual void Set() = 0;
	virtual void Show() const = 0;
};
class Waiter : virtual public Worker
{
private:
	int panache;
protected:
	void Data() const;
	void Get();
public:
	Waiter() : Worker(), panache(0) {}
	Waiter(const 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 : virtual public Worker
{
protected:
	enum { other, alto, contralto, soprano,
			bass, baritone, tenor};
	enum {Vtypes = 7};
	void Data() const;
	void Get();
private:
	static char *pv[Vtypes];
	int voice;
public:
	Singer() : Worker(), voice(other) {}
	Singer(const 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;
};
class SingingWaiter : public Singer, public Waiter
{
protected:
	void Data() const;
	void Get();
public:
	SingingWaiter() {}
	SingingWaiter(const string & s, long n, int p = 0, int v = other)
		: Worker(s, n), Waiter(s, n, p), Singer(s, n, v) {}
	SingingWaiter(const Worker & wk, int p = 0, int v = other)
		: Worker(wk), Waiter(wk, p), Singer(wk, v) {}
	SingingWaiter(const Waiter & wt, int v = other)
		: Worker(wt), Waiter(wt), Singer(wt, v) {}
	SingingWaiter(const Singer & wt, int p = 0)
		:Worker(wt), Waiter(wt, p), Singer(wt) {}
	void Set();
	void Show() const;
};
#endif

// workermi.cpp -- working class methods with MI

#include "workermi.h"
#include <iostream>
using namespace std;
Worker::~Worker() {}
void Worker::Data() const
{
	cout << "Name: " << fullname << endl;
	cout << "Employee ID: " << id << endl;
}
void Worker::Get()
{
	getline(cin, fullname);
	cout << "Enter worker's ID: ";
	cin >> id;
	while (cin.get() != '\n')
		continue;
}
void Waiter::Set()
{
	cout << "Enter waiter's name: ";
	Worker::Get();
	Get();
}
void Waiter::Show() const
{
	cout << "Category: waiter\n";
	Worker::Data();
	Data();
}
void Waiter::Data() const
{
	cout << "Panache rating: " << panache << endl;
}
void Waiter::Get()
{
	cout << "Enter waiter's panache rating: ";
	cin >> panache;
	while (cin.get() != '\n')
		continue;
}
char * Singer::pv[Singer::Vtypes] = {"other", "alto", "contralto",
		"soprano", "bass", "baritone", "tenor"};
void Singer::Set()
{
	cout << "Enter singer's name: ";
	Worker::Get();
	Get();
}
void Singer::Show() const
{
	cout << "Category: singer\n";
	Worker::Data();
	Data();
}
void Singer::Data() const
{
	cout << "Vocal range: " << pv[voice] << endl;
}
void Singer::Get()
{
	cout << "Enter number for singer's vocal range:\n";
	int i;
	for (i = 0; i < Vtypes; i++)
	{
		cout << i << ": " << pv[i] << " ";
		if (i % 4 == 3)
			cout << endl;
	}
	if ( i % 4 != 0)
		cout << '\n';
	cin >> voice;
	while (cin.get() != '\n')
		continue;
}
void SingingWaiter::Data() const
{
	Singer::Data();
	Waiter::Data();
}
void SingingWaiter::Get()
{
	Waiter::Get();
	Singer::Get();
}
void SingingWaiter::Set()
{
	cout << "Enter singing waiter's name: ";
	Worker::Get();
	Get();
}
void SingingWaiter::Show() const
{
	cout << "Category: singing waiter\n";
	Worker::Data();
	Data();
}

// workmi.cpp -- multiple inheritance
// compile with workermi.cpp

#include <iostream>
#include <cstring>
#include "workermi.h"
const int SIZE = 5;
using namespace std;
int main()
{
	Worker * lolas[SIZE];
	int ct;
	for (ct = 0; ct < SIZE; ct++)
	{
		char choice;
		cout << "Enter the employee category:\n"
			<< "w: waiter	s: singer	"
			<< "t: singing waiter	q: quit\n";
		cin >> choice;
		while (strchr("wstq", choice) == NULL)
		{
			cout << "Please enter a w, s, t, or q: ";
			cin >> choice;
		}
		if (choice == 'q')
			break;
		switch(choice)
		{
			case 'w':	lolas[ct] = new Waiter;
						break;
			case 's':	lolas[ct] = new Singer;
						break;
			case 't':	lolas[ct] = new SingingWaiter;
						break;
		}
		cin.get();
		lolas[ct]->Set();
	}
	cout <<"\nHere is your staff:\n";
	int i;
	for (i = 0; i < ct; i++)
	{
		cout << endl;
		lolas[i]->Show();
	}
	for (i = 0; i < ct; i++)
		delete lolas[i];
	cout << "Bye.\n";
	return 0;
}

输出:

wang@wang:~/c++$ ./a.out
Enter the employee category:
w: waiter    s: singer    t: singing waiter    q: quit
w
Enter waiter's name: Wally Slipshod
Enter worker's ID: 1040
Enter waiter's panache rating: 4
Enter the employee category:
w: waiter    s: singer    t: singing waiter    q: quit
s
Enter singer's name: Sinclair Parma
Enter worker's ID: 1044
Enter number for singer's vocal range:
0: other 1: alto 2: contralto 3: soprano
4: bass 5: baritone 6: tenor
5
Enter the employee category:
w: waiter    s: singer    t: singing waiter    q: quit
t
Enter singing waiter's name: Natasha Gargalova
Enter worker's ID: 1021
Enter waiter's panache rating: 6
Enter number for singer's vocal range:
0: other 1: alto 2: contralto 3: soprano
4: bass 5: baritone 6: tenor
3
Enter the employee category:
w: waiter    s: singer    t: singing waiter    q: quit
q

Here is your staff:

Category: waiter
Name: Wally Slipshod
Employee ID: 1040
Panache rating: 4

Category: singer
Name: Sinclair Parma
Employee ID: 1044
Vocal range: baritone

Category: singing waiter
Name: Natasha Gargalova
Employee ID: 1021
Vocal range: soprano
Panache rating: 6
Bye.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值