2013-08-05 174 views
0

以下main輸出的答案是「i = 10的派生類顯示」,但我不明白爲什麼?這個函數肯定是在基類型上調用的?靜態基類型和動態派生類型的輸出

這裏確定答案的思路是什麼?

class base 
{ 
    public: 
     virtual void display(int i = 10) 
     { 
      cout<<"Base class display with i = "<<i<<endl; 
     } 

}; 

class derived : public base 
{ 
    public: 
      void display(int i = 20) 
     { 
      cout<<"Derived class display with i = "<< i <<endl; 
     } 

}; 

int main(int argc, char *argv[]) 
{ 
    base *bptr = new derived; 
    bptr->display(); 

     return 0; 
} 

回答

2

看一看Can virtual functions have default parameters?

虛擬函數調用(10.3)使用默認參數在 聲明由靜態型的 的指針或引用表示所確定的虛擬功能的物體。派生類中的覆蓋函數 不會從它覆蓋的 函數獲取默認參數。

因此,bptr->display();調用的display派生版本,但使用來自base參數,靜態類型的指針bptr的。

這是因爲參數的默認值必須在編譯時確定,而動態綁定則推遲到運行時。在同一個虛擬的基礎版本和派生版本中使用不同的默認參數幾乎是保證會造成問題。當通過引用或指向基的指針調用虛擬時可能會出現問題,但執行的版本是由派生的版本定義的版本。在這種情況下,爲虛擬基本版本定義的默認參數將被傳遞給派生版本,派生版本使用不同的默認參數進行定義。

+0

好的,所以你可以使用虛函數默認參數的唯一方法是如果你聲明靜態類型是派生類?派生的d = new Derived(); – user997112

+0

@ user997112您最好使用相同的默認參數來避免任何意外。 – Yang

+0

這種行爲的原因是什麼,只有這樣我才能理解 - 而不是記住這個規則?派生類還有其他類似的規則嗎? – user997112