2017-03-15 78 views
3

我在面試中被問到這個問題。我無法在那裏回答這個問題。我現在也無法得知它,爲什麼產量是這樣。 下面是代碼:虛擬功能的超載

#include <iostream> 
using namespace std; 

class Base 
{ 
public: 
    virtual void fun (int x = 0) 
    { 
     cout << "Base::fun(), x = " << x << endl; 
    } 
}; 

class Derived : public Base 
{ 
public: 
    virtual void fun (float x = 10.0) 
    { 
     cout << "Derived::fun(), x = " << x << endl; 
    } 
}; 


int main() 
{ 
    Derived d1; 
    Base *bp = &d1; 
    bp->fun(); 
    d1.fun(); 
    d1.fun(1.2); 
    return 0; 
} 

上述代碼的輸出是:

Base::fun(), x = 0 
Derived::fun(), x = 10 
Derived::fun(), x = 1.2 

的問題是: 在我們說無論是樂趣()函數超載第一種情況(和因爲它們的聲明不同而沒有重寫)並且fun()會被調用,但fun()的這些聲明是不可能被重載的(因爲它們只是區別聲明是否包含默認參數)

void fun(int x = 0) 
void fun(float x = 10.0) 

這些函數不可能被重載。

在上述兩種情況下似乎都有矛盾。

任何相關的文章/鏈接解釋情況將是非常有益的。

+0

你期望輸出是什麼?爲什麼? – NathanOliver

+0

在第一種情況下,由於運行時多態性,輸出應該是Derived :: fun(),x = 10.0。在第二和第三種情況下,你如何決定輸出? –

回答

8

在C++中,對於重寫基類函數的成員函數,參數類型必須與基類函數的參數類型完全匹配。由於基類函數需要使用int,並且派生類的函數需要使用float,因此它不被視爲覆蓋。您可以通過使用override關鍵字看到這一點:

class Base 
{ 
public: 
    virtual void fun (int x = 0) 
    { 
     cout << "Base::fun(), x = " << x << endl; 
    } 
}; 

class Derived : public Base 
{ 
public: 
    virtual void fun (float x = 10.0) override // Doesn't compile! 
    { 
     cout << "Derived::fun(), x = " << x << endl; 
    } 
}; 

發生了什麼事在你的代碼是C++認爲你的函數是一個超載(具有相同名稱的另一個功能),而不是覆蓋。讓我們來看看下面的代碼:

Derived d1; 
Base *bp = &d1; 
bp->fun(); 

此時,由於線bp->fun()使用呼叫通過一個基類指針,C++看起來Base看到調用哪個函數。它發現Base::fun(int)。現在,由於該功能被標記爲virtual,因此它將調用Base::fun(int),除非有所改變。但由於沒有覆蓋,所以Base::fun(int)最終被調用。

那麼後面兩行呢?

d1.fun(); 
d1.fun(1.2); 

這裏,因爲你在靜態類型Derived的對象調用這些函數,C++試圖找到一個在Derived類稱爲fun功能。它發現你的新函數Derived::fun(float),並且由於C++在類中查找名稱的方式,它不會在基類中查找Base::fun(int)。因此,這兩個調用都被視爲對Derived::fun(float)的調用,所以在沒有參數出現時不會含糊不清地指出要調用哪個函數。編譯器甚至從未查看Base類型,因爲沒有必要。

因此,要總結:

  • 你介紹一個超載,不是覆蓋。使用覆蓋關鍵字將有助於您在將來診斷此類問題。
  • 通過基指針調用fun查找名爲fun功能以在int,因爲基指針的fun功能發生在一個int。這在Base找到版本,因爲沒有oerride。
  • 通過派生對象調用fun查找函數fun,從Derived開始,它會查找您的覆蓋。
+0

在第一種情況下,爲什麼運行時多態性不存在? –

+1

@YamanSingla剛剛更新瞭解釋發生了什麼事的答案。 – templatetypedef

+0

非常感謝@templatetypedef的幫助。我現在明白了究竟發生了什麼! –