C++多继承的二义性
多继承的二义性主要分为两种:
(1) 调用不同基类的同名成员时可能出现二义性
(2) 菱形继承下访问共同基类的成员可能出现二义性
/*多继承下调用不同基类的同名成员时可能出现二义性*/ #include<iostream> #include<stdio.h> using namespace std; class A { public: void setA(int a); int get() { printf("A::get()\n"); } private: int a; }; class B { public: void setB(int b); int get() { printf("B::get()\n"); } private: int b; }; class C:public A,public B { public: void setC(int c); int getC() { printf("C::getC()\n"); } private: int c; }; int main() { C obj; obj.get();//这行有问题 return 0; }
在执行obj.get();时将是有二义性的。因为类C分别从类A类B继承了两个不同版本的get()成员函数,因此,obj.get();到底调用哪个get()版本,编译器将无从知晓。
有两种解决方法:
1、使用作用域分辨符::加以消除。
obj.A::get();
obj.B::get();
2、在类C中也定义成员函数get()函数,则有类C的对象obj访问get()函数obj.get()没有二义性,这是因为当派生类中的成员与基类中的成员重名时,派生类中的同名成员将被调用。
/*访问共同基类的成员可能出现二义性*/ #include<iostream> #include<stdio.h> using namespace std; class A { public: void fun(); private: int a; }; class B1 { public: void funB1(); private: int b1; }; class B2:public A { public: void funB2(); private: int b2; }; class C:public B1,public B2 { public: void funC(); private: int c; }; int main() { /* 在此类结构下,如果创建类C的对象c1: C c1; 则下面的两个访问都有二义性: c1.fun(); c1.A::fun(); 不过下面的两条调用语句却是正确的: c1.B1::fun(); c1.B2::fun(); ***解决方法:采用虚基类的方式*** */ return 0; }