2017-08-03 40 views
1

說有兩個類:Base和Derived。代碼如下所示。 我的問題是,程序如何知道d.print()(在代碼中用A標記)是打算撥打Derived::print()而不是Base::print()C++:涉及繼承和「使用」時的方法重載

請注意,我特意加了using Base::print;來混淆編譯器。這兩個print()方法具有相同的簽名(我是對嗎?),並且由於using聲明而不相互隱藏。

#include <iostream> 
using namespace std; 

class Base { 
public: 
    void print() { cout << "print() of Base is called\n"; } 
}; 

class Derived : public Base { 
public: 
    void print() { cout << "print() of Derived is called\n"; } 
    using Base::print; // I delibarately added this line 
}; 

int main() { 
    Derived d; 
    d.print(); // A 

    Base *pBase = (Base *)&d; 
    pBase->print(); // B 
} 

結果是

print() of Derived is called 
print() of Base is called 

編輯:接受的答案給了報價。爲了方便讀者查閱我貼的(幾乎)所有引用這裏的段落,拆分句子:

使用聲明引入了一個基類到派生類定義的成員,如暴露基地的保護成員作爲派生的公共成員(這是我的預期)

如果名稱是基類的重載成員函數的名稱,則會引入具有該名稱的所有基類成員函數。 (這也是我的預期)

如果派生類已經有一個成員具有相同的名稱,參數列表和資格,派生類成員隱藏或覆蓋(不衝突)引入的成員來自基類。 (解決我的問題)

+0

好吧,也許它不是超載..?但這不是這個問題的重點。提前致謝。 – user8385554

+0

你真的很驚訝嗎? '使用Base :: print;'intorduces **所有重載**(可能有多個)。如果因爲這個原因導致你們班上的衝突,那將是非常令人痛心的。 – StoryTeller

+0

@StoryTeller這讓我感到困惑,因爲我認爲'using'聲明應該重寫名稱隱藏機制(比如「覆蓋override」),所以編譯器應該會感到困惑。但顯然這個覆蓋再次被重寫 - 畢竟,Derived :: print()覆蓋了'Base :: print()'。 – user8385554

回答

4

的明確介紹using不躲,因爲這條規則(從cppreference documentation for using

你在派生類中有方法如果派生類已經與成員相同的名稱,參數列表和資格,派生類成員隱藏或覆蓋(不衝突)從基類引入的成員。

編譯器不會混淆,它正在做正確的事情。 using未在派生類中隱藏print()方法,因爲它定義了print()方法。

當你調用print()一個Base指針,print()不虛基指針只能調用與靜態類型的它指向的東西註冊的方法,即Base::print()

+0

感謝您指出此網頁!我完全錯過了這一個。 – user8385554

+0

@ user8385554我先回答'A',然後回答'B',哪一部分讓你感到困惑? – Curious

+1

對不起,我只是承諾你的意思,所以我只是修改了我的評論.. – user8385554