2015-09-11 132 views
0

以下代碼基於C++模板:完全指南的第298頁上的示例。我刪除了與我的問題無關的部分。繼承基類成員函數的虛擬說明符

class Virtual { 
    public: 
    virtual void foo() { 
    } 
}; 

class Base : private Virtual { 
    public: 
    void foo() { 
     std::cout << "Base::foo()" << '\n'; 
    } 
}; 

class Derived : public Base { 
    public: 
    void foo() { 
     std::cout << "Derived::foo()" << '\n'; 
    } 
}; 

int main() 
{ 
    Base *p = new Derived; 
    p->foo(); // calls Derived::foo() 
} 

我不明白通話p->foo()如何結束調用Derived::foo。更具體地說,p的靜態類型是Base*Base::foo是非虛擬的。現在,Base私自繼承'虛擬',它有自己的foo,看起來好像Base::foo以某種方式從Virtual::foo獲得virtual說明符。這裏究竟發生了什麼?

+0

'Base :: foo' **是虛擬的。 –

+1

U創建了Derived的一個實例,這就是它調用Derived的方法的原因。檢查OOP繼承。 –

+0

@KerrekSB這個問題是基於一個錯誤的假設。這發生在人們身上。清除誤解幫助了我很多。這是否應該受到懲罰? – AlwaysLearning

回答

5

foovirtual繼承自基類Virtual

事實上,編寫virtualDerived::foo將是多餘的,許多開發人員將省略它。一旦您在基類中將該函數標記爲virtual,您就不能撤銷virtual

您可以通過編寫p->Base::foo();強制呼叫Base::foo,但這是一個醜陋的設計。

+0

啊。我不知何故忘記了這一點。謝謝。 – AlwaysLearning

+0

關於「你不能撤銷虛擬性」的兩個簡要說明:1)你可以用'final'來停止新的虛擬函數,以及2)如果改變函數的簽名,它將掩蓋原始的虛擬性,即使你也使用相同的簽名。 –