这个例子中,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.

C++学习笔记--多继承相关推荐

  1. C++学习笔记13-类继承

    1.  类模板的 static 成员[不同于C#中的static] 类模板能够像随意其它类一样声明static 成员.下面代码: template <class T> class Foo ...

  2. Java学习笔记3——继承

    继承 继承的好处:子类拥有父类的所有属性和方法,peivate修饰的无效:实现代码复用 class 子类 extends 父类 例如: class Dog extends Animal{...... ...

  3. 《Java 核心技术卷1 第10版》学习笔记------ 组织继承:final类和方法【编译器优化:内联( inlining );】

    使用 final 关键字阻止继承 有时候,可能希望阻止人们利用某个类定义子类.不允许扩展的类被称为 final 类.如果在定义类的时候使用了 final 修饰符就表明这个类是 final 类. 例如, ...

  4. c++学习笔记之继承和多态

    1.public 继承 class A : public B (1)友元函数不能被继承 (2)protected成员可以被派生类和友元访问 2.派生类 (1)派生类构造函数如果未显式调用基类构造函数, ...

  5. Java学习笔记_继承

    继承的格式 在继承关系中,"子类就是一个父类".也就是说,子类可以被当作父类看待 例如父类是员工,子类是讲师,那么"讲师就是一个员工" 定义父类的格式:(一个普 ...

  6. c++学习笔记(13) 继承和多态

    继承:从已有的类派生出新类 基类和派生类 不同的类之间可能有很多共通的属性和行为,这些属性和行为允许在一个类中通用化并被其他类所共享.类C1从类C2扩展而来,则C1称为派生类,C2称为基类,基类也称为 ...

  7. Spring攻略学习笔记(13)------继承Bean配置

    一:知识点 在Spring IoC容器中配置Bean时,可能拥有一个以上的共享某些公用配置的Bean,比如属性和<bean>元素中的属性.你常常需要为多个Bean重复这些配置. Sprin ...

  8. java学习笔记七——继承

    子类继承父类后子类就拥有父类的属性和方法 class a { } class b extends a { } b继承了a 转载于:https://www.cnblogs.com/huanghai/ar ...

  9. 【python面向对象学习笔记】继承

    继承 # 继承 class Animal:atype="哺乳动物"def __init__(self,name,age,sex) -> None:self.name=name ...

  10. 黑马程序员学习笔记 关于继承

    ------- <a href="http://www.itheima.com" target="blank">android培训</a> ...

最新文章

  1. CUDA and cudnn 历史版本归档地址
  2. CF1497E2 Square-free division (hard version)
  3. JavaFX教程–基础
  4. 2016 博客导读总结 amp; 个人感悟
  5. Delphi INI文件保存与读取
  6. linux vcenter6.5下载,vCenter 6.0更新至6.5
  7. 【clickhouse】clickhouse 单机安装 集群安装
  8. Spring全家桶,永远滴神!
  9. DBUtils结果集处理
  10. hive动态分区shell_hive-shell批量操作分区文件
  11. poj 3080 Blue Jeans【字符串】
  12. 谷歌离开中国的三大原因四大后果
  13. Java实验1-1【超市购物小程序】
  14. ElementUI 面试题整理
  15. python搬家具_Python语言之学会Python之后!亲朋好友都夸我厉害!用Python买到最优惠的家具...
  16. 如何把QQ和微信的语音批量导出电脑上转为MP3(小Q微转码)
  17. 微信小程序推流拉流live-pusher/live-player示例,使用本地搭建RTMP服务
  18. Scratch软件编程等级考试一级——20200913
  19. Pytorch版本过高产生的RuntimeError: Legacy autograd function with non-static forward method is deprecated.
  20. oracle快速删除1000万数据,怎么快速删除4000多万条重复的记录????

热门文章

  1. python的seek用法
  2. moss列表 查看字段长度
  3. socket(java) 搭建一个多人在线聊天室
  4. 高级系统架构师培训笔记
  5. 永久禁用software reporter 进程,占用高解决方法。【永久禁用software_reporter_tool.exe程序】
  6. 阿里云oss出现Unable to execute HTTP request: bucket.二级域名.域名: nodename nor servname provided, or not known
  7. 手机安全卫士------手机防盗页面之sim卡绑定读取联系人
  8. dropbox连接不上解决方法
  9. 身体不同部位锻炼相关英语表达
  10. 明源云预计年亏超7亿元:被花旗下调评级,“人脸识别”遭质疑