2015-10-04 42 views
-1

我想在C++中嘗試運行時多態。有人能解釋我這個程序的輸出嗎?我運行它,它給了我一個Derived的輸出(意味着派生類的函數f()被調用)。另外,如果我取消註釋語句 - 程序的預期行爲是什麼 - d.f(); ?C++運行時多態 - 關於默認參數

// Example program 
#include <iostream> 
#include <string> 

class Base { 
    public :virtual void f(int a = 7){std::cout << "Base" <<std::endl;} 
}; 
class Derived : public Base { 
    public :virtual void f(int a) {std::cout << "Derived" <<std::endl;} 
}; 

int main() { 
    Derived d; 
    Base& b = d; 
    b.f(); 
    //d.f(); 

    return 0; 
} 
+0

如果你想確保你的'Derived :: f()'在你的'Base :: f()'上按照預期工作,你可以在函數聲明之前使用關鍵詞'override',例如: 'virtual void f(int a)override {std :: cout <<「Derived」<< std :: endl; }'這將確保預期派生函數的正確函數將被調用,以給你實現你想要的。 –

回答

1

默認參數在編譯時解析。因此對於編譯器來說,你正在做b.f(7);

由於f是虛擬的,並且實際的b是派生的,因此派生的f()在運行時被調用,因爲運行時將查找對象的vTable,並且它會找到Derived的f()。

此外,如果我取消註釋 語句的程序的預期行爲是什麼 - d.f(); ?

我期望編譯器錯誤,因爲編譯器會查找Derived :: f並且沒有默認參數。

+1

d.f()確實存在編譯錯誤。 –

+0

@CaptainGiraffe感謝您的確認,我沒有嘗試:) –

+0

@ A.S.H:派生類函數f()如何在不期望參數時使用參數? – chrisrhyno2003

0

當您在對象上調用函數時,必須在編譯時找到該函數。在運行時,被調用的實際函數取決於運行時調度機制。

在你的情況下,呼叫

b.f(); 

得到在編譯時有a設置該參數的默認值的值解析爲Base::f(int)

呼叫

d.f(); 

將編譯失敗。該功能解析爲Derived::f(int)。但是,由於Derived::f(int)沒有該參數的默認值,因此在調用該參數時必須提供一個值。

d.f(10); 

將工作。

在運行時,該調用解析爲Derived::f(int),因爲沒有其他實現覆蓋它。