您的位置:首页 > 编程语言 > C语言/C++

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

2016-10-15 18:34 141 查看
这个例子中,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()
{
4000

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: