虚基类:简单来说如下:
假如有基类B,从B派生出C和D,然后类F又同时继承了C和D,现在类F的一个对象里面包含了两个基类B的对象,如果F访问自己的从基类B那里继承过来的的数据成员或者函数成员那么编译器就不知道你指的到底是从C那里继承过来的B对象呢还是从D那里继承过来的B对象。
于是虚基类诞生了,将C和D的继承方式改为虚继承,那么F访问自己从B那里继承过来的成员就不会有二义性问题了,也就是将F对象里的B对象统一为一个,只有一个基类B对象。
于是我写了一段代码,worker是基类,waiter和singer是worker的派生类,singing waiter是waiter和singer的派生类。
// // Created by lenovo on 2018/5/12. // #ifndef PROJECT_1_WORKERMI_H #define PROJECT_1_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];//voice range 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 p=0,int v=other): worker(wt),waiter(wt),singer(wt,v){} singingwaiter(const singer& wt,int p=0,int v=other): worker(wt),waiter(wt,p),singer(wt){} void set(); void show() const; }; #endif //PROJECT_1_WORKERMI_H
// // Created by lenovo on 2018/5/12. // #include "workerMI.h" #include <iostream> using namespace std; worker::~worker() {} void worker::data() const{ cout<<"name: "<<fullname<<endl; cout<<"ID: "<<ID<<endl; } void worker::get() { getline(cin,fullname); cout<<"enter worker's ID: "; cin>>ID; while(cin.get()!='\n') continue; } //waiter void waiter::data() const { cout<<"panache: "<<panache<<endl; } void waiter::get() { cout<<"enter waiter's panache rating: "; cin>>panache; while(cin.get()!='\n') continue; } void waiter::set() { cout<<"the waiter's name: "; worker::get(); get(); } void waiter::show() const { cout<<"category: waiter\n"; worker::data(); data(); } //singer void singer::data() const { cout<<"vocal range: "<<pv[voice]<<endl; } void singer::get() { cout<<"enter number for singer's vocal range:\n"; for (int 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 singer::set() { cout<<"enter singer's name:"; worker::get(); get(); } void singer::show() const { cout<<"category: singer\n"; worker::data(); data(); } //singingwaiter 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(); }
#include <iostream> #include <cstring> #include "workerMI.h" using namespace std; const int size=5; int main(){ worker* lolas[size]; int ct; for (ct = 0; ct < size; ct++) { char choice; cout<<"enter the employee catagory:\n" <<"w:waiter s:singer " <<"t:singing waiter q:quit\n"; cin>>choice; while (strchr("wstq", choice) == NULL){ cout << "please enter w,s,t,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; default: break; } cin.get(); lolas[ct]->set(); } cout<<"\nhere is your staff:\n"; for (int j = 0; j < ct; j++) { cout<<endl; lolas[j]->show(); } for (int i = 0; i < ct; i++) { delete lolas[i]; } cout<<"Bye.\n"; return 0; }在以上读者看见多态继承的使用方法,只不过这种方法比较复杂,日常中用的不多。