从多重继承中的二义性 到 虚基类(摘抄自谭浩强c++)

来源:互联网 发布:可以写作的软件 编辑:程序博客网 时间:2024/06/06 01:01

一个多重继承的程序

#include<iostream>using namespace std;class Teacher{public:    Teacher(string nam,int a,string t):name(nam),age(a),title(t){}    void display()    {        cout << "name:" << name << endl;        cout << "age:" << age << endl;        cout << "title:" << title << endl;    }protected:    string name;    int age;    string title;};class student{public:    student(string nam,char a,float sco):name(nam),sex(a),score(sco){}    void display()    {        cout << "name:" << name << endl;        cout << "sex:" << sex << endl;        cout << "score:" << score << endl;    }protected:    string name;    char sex;    float score;};class Graduate:public Teacher,public student{public:    Graduate(string nam,int a,char s,string t,float sco,float w):Teacher(nam,a,t),student(nam,s,sco),wage(w){}    void show()    {        cout << "name:" << name << endl;        //cout << "name:" << Teacher::name << endl;        cout << "age:" << age << endl;        cout << "sex:" << sex << endl;        cout << "score:" << score << endl;        cout << "title:" << title << endl;        cout << "wages:" << wage << endl;    }private:    float wage;};int main(){    Graduate grad1("Wang -li",24,'f',"assistant",89.5,1234.5);    grad1.show();    return 0;}


编译错误,

C:\Users\Administrator\Desktop\test - cpp\test.cpp||In member function 'void Graduate::show()':|
C:\Users\Administrator\Desktop\test - cpp\test.cpp|42|error: reference to 'name' is ambiguous|
C:\Users\Administrator\Desktop\test - cpp\test.cpp|31|error: candidates are: std::string student::name|
C:\Users\Administrator\Desktop\test - cpp\test.cpp|15|error:                 std::string Teacher::name|
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

 reference to 'name' is ambiguous   研究生的两个基类都有同名的成员 name,导致二义性。

作程序中被注释掉的修改后,程序可以继续运行。Teacher::name



尝试用同名覆盖来解决这个问题:

#include<iostream>using namespace std;class Teacher{public:    Teacher(string nam,int a,string t):name(nam),age(a),title(t){}    void display()    {        cout << "name:" << name << endl;        cout << "age:" << age << endl;        cout << "title:" << title << endl;    }protected:    string name;    int age;    string title;};class student{public:    student(string nam,char a,float sco):name(nam),sex(a),score(sco){}    void display()    {        cout << "name:" << name << endl;        cout << "sex:" << sex << endl;        cout << "score:" << score << endl;    }protected:    string name;    char sex;    float score;};class Graduate:public Teacher,public student{public:    Graduate(string nam,int a,char s,string t,float sco,float w):Teacher(nam,a,t),student(nam,s,sco),name(nam),wage(w){}    void show()    {        cout << "name:" << name << endl;        //cout << "name:" << Teacher::name << endl;        cout << "age:" << age << endl;        cout << "sex:" << sex << endl;        cout << "score:" << score << endl;        cout << "title:" << title << endl;        cout << "wages:" << wage << endl;    }//private:public:    string name;    float wage;};int main(){    Graduate grad1("Wang -li",24,'f',"assistant",89.5,1234.5);    grad1.show();    cout << endl;    cout << "Graduate's name:" << grad1.name;    return 0;}
只是给Graduate类增加了一个name成员变量,然后利用同名覆盖解决了问题。


用虚基类来解决问题:

#include<iostream>using namespace std;class Person{public:    Person(string nam,char s, int a):name(nam),sex(s),age(a){}protected:    string name;    char sex;    int age;};class Teacher:virtual public Person{public:    Teacher(string nam,char s,int a,string t):Person(nam,s,a),title(t){}    void display()    {        cout << "name:" << name << endl;        cout << "sex:" << sex << endl;        cout << "age:" << age << endl;    }protected:    string title;};class student:virtual public Person{public:    student(string nam,char s,int a,float t):Person(nam,s,a),score(t){}    void display()    {        cout << "name:" << name << endl;        cout << "sex:" << sex << endl;        cout << "age:" << age << endl;        cout << "score:" << score << endl;    }protected:    float score;};class Graduate:public Teacher,public student{public:    Graduate(string nam,char s,int a,string t,float sco,float w):Person(nam,s,a),Teacher(nam,s,a,t),student(nam,s,a,sco),wage(w){}    void show()    {        cout << "name:" << name << endl;        //cout << "name:" << Teacher::name << endl;        cout << "age:" << age << endl;        cout << "sex:" << sex << endl;        cout << "score:" << score << endl;        cout << "title:" << title << endl;        cout << "wages:" << wage << endl;    }//private:public:    float wage;};int main(){    Graduate grad1("Wang -li",'f',24,"assistant",89.5,1234.5);    grad1.show();    cout << endl;    student srm("srm",'b',25,1234.5);    srm.display();    return 0;}
使用了虚基类的办法,Gradute类只保留了一份person类的数据,需要注意的是gradute类的构造函数中,实际上是只由gradute类的构造函数完成person类的初始化。


0 0