2016-01-06 112 views
-1

我有一個基類A和一個派生類B.A和B都定義了[]運算符,但不具有相同的參數類型。儘管如此,當我嘗試在A類型的對象上使用[]運算符時,arg C++沒有找到A的def。很煩人。什麼是規則?C++運算符繼承和重載

+5

你能告訴你使用使用在[MCVE]代碼? – NathanOliver

+0

你是說你想打電話給A的操作員[]? – thefunkyjunky

+0

@NathanOliver這就是問題所在:要提供一個純粹的必需品清潔版供您檢查。如果你不知道任何禁止我試圖做的規則,我可能不得不這樣做。 – Henrik

回答

3

B類中的運算符隱藏了A類中的運算符。這是派生類中定義的任何方法的問題,它們重載超類中的方法。如果名稱查找在B中找到名稱匹配,則它不會查找A,即使在B中找到的匹配不能被調用。

你需要把它納入B的範圍:

class X{}; 
class Y{}; 

class A { 
public: 
    auto operator[](X) {}; 
}; 

class B : public A { 
public: 
    using A::operator[]; // <-- you need this 
    auto operator[](Y){}; 
}; 


int main() { 
    A a; 
    B b; 
    b[X{}]; // OK 
    b[Y{}]; // OK 
} 
+0

謝謝,這就是我想知道的。不過,我不明白爲什麼C++的行爲如此。如果它在B類中找不到操作數匹配,它應該在A中查找。當然!這就是完整的繼承點。 – Henrik

+1

@亨利克 - 不,那會導致神祕的錯誤。假設你已經寫了一個從庫類派生的類,並且你的類有一個成員函數'void foo(double);'。你可以用一個類型爲「int」的參數來調用它,並且該參數將被轉換爲「double」以便進行調用。現在假設庫的維護版本向該基類「void foo(int);'添加了一個成員函數。現在你的代碼會悄悄地調用基類版本,而不是你的版本。 –

+0

@Pete,我不同意。如果第三方提供庫類,它應該發佈帶​​有文檔的接口,並且它必須保持固定。無論做出什麼樣的改變,只應該影響隱藏的代碼,而不會影響用戶界面或功能。向後兼容性至關重要。這就是行業標準如此緩慢變化的原因。 – Henrik