C++多重繼承二義性解決


1. 什么是多重繼承的二義性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class  A{
public :
     void  f();
}
 
class  B{
public :
     void  f();
     void  g();
}
 
class  C: public  A, public  B{
public :
     void  g();
     void  h();
};

 如果聲明:C c1,則c1.f();具有二義性,而c1.g();無二義性(同名覆蓋)。

2. 解決辦法一 -- 類名限定

調用時指名調用的是哪個類的函數,如

1
2
c1.A::f();
c1.B::f();

3. 解決辦法二 -- 同名覆蓋

在C中聲明一個同名函數,該函數根據需要內部調用A的f或者是B的f。如

1
2
3
4
5
6
7
8
class  C: public  A, public  B{
public :
     void  g();
     void  h();
     void  f(){
         A::f();
     }
};

 4. 解決辦法三 -- 虛基類(用於有共同基類的場合)
virtual 修飾說明基類,如:

1
class  B1: virtual  public  B

虛基類主要用來解決多繼承時,可能對同一基類繼承繼承多次從而產生的二義性。為最遠的派生類提供唯一的基類成員,而不重復產生多次拷貝。注意:需要在第一次繼承時就要將共同的基類設計為虛基類。虛基類及其派生類構造函數建立對象時所指定的類稱為最(遠)派生類。

  • 虛基類的成員是由派生類的構造函數通過調用虛基類的構造函數進行初始化的。
  • 在整個繼承結構中,直接或間接繼承虛基類的所有派生類,都必須在構造函數的成員初始化表中給出對虛基類的構造函數的調用。如果未列出,則表示調用該虛基類的缺省構造函數。
  • 在建立對象時,只有最派生類的構造函數調用虛基類的構造函數,該派生類的其他基類對虛基類的構造函數的調用被忽略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class  B{
     public :
     int  b;
}
 
class  B1: virtual  public  B{
     priavte:
     int  b1;
}
 
class  B2:virutual  public  B{
     private :
     int  b2;
}
 
class  C: public  B1, public  B1{
     private :
     float  d;
}
 
C obj;
obj.b; //正確的

 如果B1和B2不采用虛繼續,則編譯出錯,提示“request for member 'b' is ambiguous”。這是因為,不指名virtual的繼承,子類將父類的成員都復制到自己的空間中,所以,C中會有兩個b。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include<iostream>
using  namespace  std;
 
class  B0{
public :
     B0( int  n)    {
         nv=n;
         cout<< "i am B0,my num is" <<nv<<endl;
     }
     void  fun()    {
         cout<< "Member of Bo" <<endl;
     }
private :
     int  nv;
};
 
class  B1: virtual  public  B0{
public :
     B1( int  x, int  y):B0(y){
        nv1=x;
        cout<< "i am  B1,my num is " <<nv1<<endl;
     }
private :
     int  nv1;
};
 
class  B2: virtual  public  B0{
public :
     B2( int  x, int  y):B0(y){
         nv2=x;
         cout<< "i am B2,my num is " <<nv2<<endl;
     }
private :
     int  nv2;
};
 
class  D: public  B1, public  B2{
public :
     D( int  x, int  y, int  z, int  k):B0(x),B1(y,y),B2(z,y){
        nvd=k;
        cout<< "i am D,my num is " <<nvd<<endl;
     }
private :
     int  nvd;
};
 
int  main(){
     D d(1,2,3,4);
     d.fun();
     return  0;
}

 d.fun()的結果是:

1
2
3
4
5
i am B0,my num is 1
i am B1,my num is 2
i am B2,my num is 3
i am D,my num is 4
Member of Bo

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM