2013-03-19 125 views
0
#include<iostream> 
using namespace std; 

class base 
{ 
    public: 
     virtual void f(){} 
}; 

class middle1:public base 
{}; 

class middle2:public base 
{}; 

class derive:public middle1,public middle2 
{}; 



int main() 
{ 
    derive* pd=new derive(); 
    pd->f(); 
    return 0; 
} 

我知道虛擬解決了這個問題,但是怎麼樣? 即使我們沒有多重繼承,我們是否可以始終爲安全編寫公共虛擬?A類有什麼區別:公共虛擬B和A類:public B

+0

虛擬告訴編譯器從基地獲取方法和成員變量的副本,而不是從中間2 – Prasad 2013-03-19 11:37:12

回答

2

derive的每個實例都有一個middle1基類子對象和一個middle2基類子對象。

如果繼承非虛擬的,則middle1基類子對象具有base基類子對象,middle2基類子對象也具有base基類的子對象。因此,中derive每個實例有兩個base子對象,呼叫pd->f()是模糊的 - 它的base的對象,你要調用f()嗎?

使繼承虛擬意味着middle1middle2將共享derive的一個base子對象。這消除了歧義 - 只有一個base對象可以調用f()

我們能總是寫的公共虛擬安全

不一定。有可能是繼承層次中,你不希望middle1middle2共享一個公共base子對象。你可能會認爲,在這種情況下,你不應該寫一個類derive來自兩個繼承,但如果你做這種情況最終會那麼解決辦法是做兩種:

static_cast<middle1*>(pd)->f(); 
pd->middle1::f(); 

指定要叫fmiddle1基類的子對象,或

static_cast<middle2*>(pd)->f(); 
pd->middle2::f(); 

指定middle2

1

我知道虛擬解決了這個問題,但是怎麼樣?

virtual關鍵字通過使只有一個頂部順序基類子對象存在於繼承層次結構解決了這個問題。沒有它,每個父類middle1 & middle2都有它們自己的base類的副本,因此導致含糊不清。

即使我們沒有多重繼承,我們是否可以總是寫出公共虛擬的安全性?

如果沒有多重繼承,沒有理由使用virtual繼承。多重繼承是虛擬繼承概念存在的目的。

1

虛擬基類中爲了解決金剛石問題(見this question)實施附加間接級。

如果你總是使用虛擬繼承,你總是會遭受額外的間接層面造成的性能損失。

因此,我建議,當你有你只使用虛擬繼承。

相關問題