2011-10-20 94 views
3

我從電子書模板完整的指導和問題,其中我要去問可能是愚蠢的,你讀,但..混亂了解虛擬函數調用和依賴的基類

存在這樣9.4.2相關部分基礎類,我無法理解。

下面是它的部分文字:http://tinypaste.com/633f0

// Variation 2: 
template<typename T> 
class DD2 : public Base<T> { 
    public: 
    void f() { Base<T>::basefield = 0; } 
}; 

我需要幫助可視化線(或問題域)在上面的文字「必須注意與此解決方案,因爲如果不合格的非依賴的名字被用來形成一個虛擬函數調用,然後該資格禁止虛擬調用機制和程序變化的含義。但是,有些情況下,第一個變體不能使用,這種替代方法是合適的「

我明白unqual ified非依賴名稱等,但將它們與虛擬函數調用混合在一起是什麼讓我難以置信。

+4

這是一個可怕的錯誤是不是這個代碼似乎被設計爲允許非虛擬多態的行爲。即你的派生類可以覆蓋你的基類中的方法,但查找是在編譯時完成的。我懷疑在這個意義上「禁止」意味着你不會得到通常的基於vtable的動態運行時查找.... – Benj

+0

需要更多的上下文。這個代碼試圖解決什麼問題? –

回答

2

如果限定名稱(basefield)是虛擬功能,則限定條件禁止虛擬呼叫。這是非常相同的,如果您有:

struct Base { 
    virtual void vCall() { } 
}; 

struct Derived : public Base { 
    virtual void vCall() { } 
}; 

int main() { 
    Derived d; 
    Base* inst = &d; 
    inst->Base::vCall(); // By qualifying we won't get virtual dispatch; 
         // this calls Base::vCall directly 
} 
1

使用合格的標識符class-name::function()抑制function虛擬的煩躁,所以你應該使用this->function()代替。

這也適用於數據成員:this->basefield