1 class A 2 { 3 4 public: 5 void f(); 6 } 7 8 class B 9 { 10 public: 11 void f(); 12 void g(); 13 } 14 15 class C:public A,public B 16 { 17 public: 18 void g(); 19 void h(); 20 };
如果声明:C c1
则c1.f();具有二义性
而c1.g();无二义性(同名覆盖)
解决方法:
1:类名限定
c1.A::f();
c1.B::f();
2:同名覆盖
在C中声明一个同名函数,该函数根据需要内部调用A的f或者是B的f
1 class B 2 { 3 public: 4 int b; 5 } 6 7 class B1:public B 8 { 9 private: 10 int b1; 11 } 12 13 class B2:public B 14 { 15 private: 16 int b2; 17 } 18 19 class C:public B1,public B2 20 { 21 public: 22 int f(); 23 private: 24 int d; 25 } 26 27 C c; 28 c.B1::b;(对) 29 c.B::b;(错)
2:虚基类
用于有共同基类的场合
声明
virtual 修饰说明基类
class B1:virtual public B
主要用来解决多继承时,可能对同一基类继承继承多次从而产生的二义性。
为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝。
注意:需要在第一次继承时就要将共同的基类设计为虚基类
1 class B 2 { 3 public: 4 int b; 5 } 6 7 class B1:virtual public B 8 { 9 priavte: 10 int b1; 11 } 12 13 class B2:virutual public B 14 { 15 private: 16 int b2; 17 } 18 19 class C:public B1,public B1 20 { 21 private: 22 float d; 23 } 24 25 C obj; 26 obj.b;//正确的
虚基类及其派生类构造函数
建立对象时所指定的类称为最(远)派生类
①:虚基类的成员是由派生类的构造函数通过调用虚基类的构造函数进行初始化的。
②:在整个继承结构中,直接或间接继承虚基类的所有派生类,都必须在构造函数的成员初始化表中给出对虚基类的构造函数的调用。如果未列出,则表示调用该虚基类的缺省构造函数。
③:在建立对象时,只有最派生类的构造函数调用虚基类的构造函数,该派生类的其他基类对虚基类的构造函数的调用被忽略。
1 #例子: 2 #include<iostream> 3 using namespace std; 4 5 class B0 6 { 7 public: 8 B0(int n) 9 { 10 nv=n; 11 cout<<"i am B0,my num is"<<nv<<endl; 12 } 13 void fun() 14 { 15 cout<<"Member of Bo"<<endl; 16 } 17 private: 18 int nv; 19 }; 20 21 class B1:virtual public B0 22 { 23 public: 24 B1(int x,int y):B0(y) 25 { 26 nv1=x; 27 cout<<"i am B1,my num is "<<nv1<<endl; 28 } 29 private: 30 int nv1; 31 }; 32 33 class B2:virtual public B0 34 { 35 public: 36 B2(int x,int y):B0(y) 37 { 38 nv2=x; 39 cout<<"i am B2,my num is "<<nv2<<endl; 40 } 41 private: 42 int nv2; 43 }; 44 45 class D:public B1,public B2 46 { 47 public: 48 D(int x,int y,int z,int k):B0(x),B1(y,y),B2(z,y) 49 { 50 nvd=k; 51 cout<<"i am D,my num is "<<nvd<<endl; 52 } 53 private: 54 int nvd; 55 }; 56 57 int main(void) 58 { 59 D d(1,2,3,4); 60 d.fun(); 61 return 0; 62 }