C++多重继承的二义性的理解

 

多重继承的二义性:如下代码,

当创建了两个基类以后,派生类继承自两个基类,其中两个基类具有相同名称的函数。

在主函数中创建派生类的对象,当派生类的对象调用show函数,系统则分不清该调用的哪一个基类的show()函数。当在编译器执行时也会报错。

#include 
using namespace std;
class Base1{
    protected:
        int i;//属性 
    public:
        void show()
        {
            cout << i << endl;
        }
};
class Base2{
    protected:
        int i;
    public:
        void show()
        {
            cout << i << endl;
        }
};
class Derived:public Base1,public Base2{
    public:
        void set_ii(int x, int y){
            Base1::i = x;
            Base2::i = y;
            //解决二义性的办法 
            //因为Base1和Base2里面各有一个i
            //类名称::i    作用域操作符 
        }
};
int main(){
    Derived obj;
    obj.set_ii(5,7);//完成初始化的操作 
    obj.show();//会报错   两个父类都有show函数,所以系统分不清楚就不知道是哪一个show函数 
    obj.Base1::show();
    obj.Base2::show();
    return 0;
}

多重继承引发的问题

#include 
using namespace std;
class Person{
    string name;
}; 
class Student : public Person{
    string major;
    int id;
};
class Professor : public Person{
    string title;
    string id;
};
class ProfessorStudent : public Student, public Professor{
    //在大学期间会有学生是老师的助理,所以他既有老师的特性也有学生的特性
  //所以继承下来name就有重复,而id则会有冲突 };

在C++中有办法解决这种重复和冲突的现象

多重继承中除了属性会发生冲突以外,在函数之中也会发生冲突

C++多重继承的二义性的理解_第1张图片

 

 

//未用虚拟继承
#include using namespace std; class A{ protected: int a; public: void f(); }; class B:public A{ protected: int b; }; class C:public A{ protected: int c; }; class D:public B,public C{ protected: int d; public: void h() { f();//系统会报错 reference to 'f' is ambiguous
       //解决办法也可以是A::f();
       //通过基类的名称做作用域操作符调用函数的方式来解决从不同线路继承下来的一个问题 } };
void D::h(){
    f();//可以改成A::f(); 
}
void main(){
    D obj;
    obj.f();//可以改成obj.A::f() 
} 
 
  

 

 

 (这里数据a把继承了两次,解决办法就是通过虚基类,来解决存储重复的方法)

 

 要想解决如上的报错可以通过虚基类来避免此类的二义性(说明:这里虽然起到解决二义性的问题,但是主要要讲解的知识是解决存储重复问题),下图是存储结构示意图

C++多重继承的二义性的理解_第2张图片

 

 

//采用虚拟继承
#include using namespace std; class A{ protected: int a; public: void f(); }; class B:virtual public A{ protected: int b; }; class C:virtual public A{ protected: int c; }; class D:public B,public C{ protected: int d; public: void h() { f(); } }; void main(){ D obj; //创建对象 obj.f(); }

如果B和C不采用虚拟继承,则编译报错,系统会报错 reference to 'f' is ambiguous

这是因为,不指名virtual的继承,子类将父类的成员都复制到自己的空间中,所以,D中会有两个f()。

void D::h(){f();//可以改成A::f(); }void main(){D obj;obj.f();//可以改成obj.A::f() } 

你可能感兴趣的:(C++多重继承的二义性的理解)