2016-01-06 110 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