2012-07-14 67 views
0

可能重复:
overloaded functions are hidden in derived class无法使用基类的方法

看来我不能直接使用在派生类从基类的方法是当它们存在在两个重载基类和C++中的派生类。以下代码会产生错误no matching function for call to ‘Derived::getTwo()’

class Base { 
public: 
    int getTwo() { 
     return 2; 
    } 
    int getTwo(int, int) { 
     return 2; 
    } 
}; 

class Derived : public Base { 
public: 
    int getValue() { 
     // no matching function for call to ‘Derived::getTwo()’ 
     return getTwo(); 
    } 
    int getTwo(int) { 
     return 2; 
    } 
}; 

如果我改变return getTwo();return ((Base*) this)->getTwo(),它的工作原理,但是这看起来丑陋给我。我怎样才能解决这个问题?

P.S.如果有问题,我使用g ++ 4.7和std = gnu ++ c11选项。

+0

这将肯定会作为重复关闭,但同时,快速的答案是在类范围中将'Base :: getTwo'添加到您的Derived'定义中。 – ildjarn 2012-07-14 00:26:45

回答

1

或者:

class Derived : public Base { 
public: 
    using Base::getTwo; // Add this line 
    int getValue() { 
     // no matching function for call to ‘Derived::getTwo()’ 
     return getTwo(); 
    } 
    int getTwo(int) { 
     return 2; 
    } 
} 

或者

 return Base::getTwo(); 
+0

谢谢!你能解释一下为什么这个工作吗?或者说,为什么它不会呢? – RPFeltz 2012-07-14 00:35:31

+0

@RPFeltz:它被称为*隐藏*,基本上这个过程就是查找从最接近的上下文开始(在'getValue()'method + ADL)内部开始),并且如果找不到'getTwo ,然后检查下一个范围,依此类推。一旦它在一个上下文中找到标识符,就停止搜索。在你的情况下,它会在你的类中找到'int getTwo(int)',所以它不会查看其他重载的基类。这两种替代解决方案是:使用'base :: getTwo;'将基本重载带入派生类作用域,以便它可以在类中使用... – 2012-07-14 00:56:43

+0

...然后重载解析将选择最合适的超载。另一种解决方法是用'base :: getTwo()'限定调用,这会告诉编译器,你想从基类上下文中获得'getTwo()'(即避免在当前范围内开始查找并跳转到'getTwo ''在基地''') – 2012-07-14 00:58:54

0

这是如何在C名称查找++工程:

namespace N1 
{ 
    int getTwo(); 
    int getTwo(int, int); 

    namespace N2 
    { 
     int getTwo(int); 

     namespace N3 
     { 
      call getTwo(something char*); 
     } 
    } 
} 

当前上下文是N3。此层上没有getTwo。好吧,去上层。 N2包含getTwo的一个定义。编译器会尝试使用这个定义并且不会访问上面的上下文。来自N2的getTwo隐藏了所有较高层上的getTwo的所有定义。有时这会导致重载方法的混淆。

如果您添加using Base::getTwo;,则实际上会为内部上下文添加定义代理。上下文快照的定义不可见。但代理是可见的。