2013-02-17 39 views
9

我需要理解爲什麼C++不允許在Child中訪問祖父母重載函數,如果任何重載函數在Parent中聲明。考慮下面的例子:祖父母在兒童中的重載函數

class grandparent{ 
public: 
    void foo(); 
    void foo(int); 
    void test(); 
}; 

class parent : public grandparent{ 
public: 
    void foo(); 
}; 

class child : public parent{ 
public: 
    child(){ 
     //foo(1); //not accessible 
     test(); //accessible 
    } 
}; 

這裏,兩個函數foo()和foo(int)是祖父母中的重載函數。但是FOO(INT)不是因爲FOO訪問()在父聲明(沒關係,如果它是聲明公共或私人或保護)。但是,test()是可訪問的,按照OOP是正確的。

我需要知道這種行爲的原因。

回答

10

原因是方法隱藏

當你在派生類中聲明具有相同名稱的方法,與該名稱基類的方法是隱藏的。完整的簽名無關緊要(即cv-qualifiers或參數列表)。

如果你明確要允許呼叫,您可以使用

using grandparent::foo; 

parent

+0

是否有一個原因,這種行爲是一件好事嗎? (即**爲什麼**,因爲什麼原因,而不是*爲什麼*因爲在什麼原因造成的) – 2013-02-17 23:55:47

+1

@SanjayManohar我看到的唯一用途就是防止錯誤 - 即認爲你從父母調用方法,實際上是從祖父母中調用一種方法,因爲你錯過了輸入參數。你可以用'using'指令繞過它。 – 2013-02-17 23:57:42

+0

@SanjayManohar請參閱http://stackoverflow.com/questions/4837399/c-rationale-behind-hiding-rule – 2013-02-18 00:10:49

1

試想一下,一個圖書館有這個類:

struct Base { 
}; 

在你的代碼使用該類作爲基類:

struct Derived : Base { 
    void f(int); 
}; 

,現在你寫:

Derived d; 
d.f('a'); 

現在你該庫的2.0閃亮的新版本,和基類已經改變了一點:

struct Base { 
    void f(char); 
} 

如果在此處應用了重載,那麼您的代碼將會中斷。