2012-03-12 83 views
1

明確解釋在以下情況下方法解析規則爲。我有一個想法,基於代碼的行爲,但想澄清。我的方法調用如何解決?

基於「調用對象的常量性決定了哪個版本MYARRAY的::獲取()將被調用,因此不論是否來電給出與他就可以操縱或僅觀察到的私人數據的引用這兩個方法在技術上有不同的簽名,因爲它們的「this」指針有不同的類型,允許編譯器從wikipedia const correctness中選擇合適的「,我會得出結論,我的例子應該是方法重載的情況,而不是方法覆蓋(因爲const方法和非const方法有兩個不同的簽名)。

class Base 
{ 
public: 

    void test() 
    { std::cout << "nonconst call" << std::endl; } 
}; 

class Child : public Base 
{ 
public: 

    void test() const 
    { 
     std::cout << "const call" << std::endl; 
     Child * nonConstThis = const_cast<Child * >(this); 
     Base * nonConstBase = dynamic_cast<Base * >(nonConstThis); 

     // This call leads to infinite recursion by calling 
     // "void Child::test() const", which implies that 
     // a "Child *" will resolve to calling a const Child function 
     // before calling a non-const Base function. 
     //nonConstThis->test(); 

     // This will call "void Base::test()" 
     nonConstBase->test(); 
    } 

}; 

void main() 
{ 
    Child * child = new Child; 
    child->test(); 
} 

回答

3

它實際上是方法隱藏,而不是超載。

當您在派生類中創建具有相同名稱的方法時,基類版本不再可見。

struct A 
{ 
    void foo() {} 
}; 

struct B : public A 
{ 
    void foo(int x) {} 
}; 

B b; 
b.foo(); //error 

我假設你指望B::foo()存在,但是,正如你所看到的,它不會。所以沒有什麼,不是cv-qualifiers(const)或參數會影響這個。

在你的情況名未得到解決,因爲它有事情做與const,而是因爲你Child類型的對象上調用test。然後調用Base::test()Base類型的對象,就像下面將努力形成我的例子:

((A)b).foo(); 
+0

對。 'Child'中的const版本隱藏'Base'中的非const版本,並防止它成爲重載。 – 2012-03-12 20:35:39

3

你是超負荷名稱解析使用C是如何工作的絆腳石++。基類中的「測試」功能變爲「隱藏」(稱爲名稱隱藏)。當尋找合適的函數進行調用時,編譯器首先在派生類中查找,看到匹配,然後停止查找。 This answer has a good description as to why

您可以使用using聲明在基類看起來也像這樣:

class Child : public Base 
{ 
public: 
    using Base::test; 

這將告訴編譯器也期待在基地試驗。

+0

據我所知,沒有問題需要解決。 – 2012-03-12 20:36:41

+0

@zdan這說明了一些事情。此外,我剛剛證實,使基本虛擬葉Base :: test()暴露。 – 2012-03-12 20:51:50

相關問題