2016-01-21 49 views
1

我有两个类:CPP多态性和继承 - 编译器没有发现方法

template<typename T> 
class A{ 
    public: 
     T& someMethod(std::string); 
} 

template<typename T> 
class B: public A<T>{ 
public: 
    T& someMethod(T&,T&); 
} 

我的问题是,知道我不能叫

B b; 
b.someMethod("HelloWorld"); 

,因为我的编译器看不到someMethod(std::string) 。你知道为什么这样吗?

+0

重复http://stackoverflow.com/questions/411103/function-with-same-name-but-different-signature-in-derived-class – Sasha

+0

我想补充说 ** B b; b.someMethod(“HelloWorld”); ** 表明您根本没有使用多态,只有继承 – Guiroux

+0

在提供的示例中没有多态。 – SergeyA

回答

7

是的,这是名称隐藏。你应该添加使用声明。

template<typename T> 
class B: public A<T>{ 
public: 
    using A<T>::someMethod; 
    T& someMethod(T&,T&); 
}; 
0

你知道这是为什么吗?

是的。


在范围中查找名称期间,当范围具有名称定义时,定义搜索将停止从包含到封闭范围。而类继承被认为是嵌套的范围(有些注意事项与当前讨论无关,以处理多重继承)。因此,当找到someMethod的B定义时,搜索停止和A未被查找.ForEveR给出了将A的定义导入B的方法,其中using

请注意,搜索算法是一个通用规则,适用于其他类型的嵌套作用域,块(但块的函数声明不是现在经常做的事情)和名称空间(尝试定义重载函数ns1 :: someFunction和ns2 :: someFunction,在ns2中,如果不导入它的声明,您将无法调用ns1 :: someFunction)。

0

问题是派生类中的方法隐藏了具有相同名称的基类的所有方法。

要调用基类方法,您必须使用限定名称。

例如

#include <iostream> 
#include <string> 

template<typename T> 
class A{ 
    public: 
     T& someMethod(std::string s) 
     { 
      static T t; 
      std::cout << "A::someMethod: " << s << std::endl; 
      return ++t; 
     } 
}; 

template<typename T> 
class B: public A<T>{ 
public: 
    T& someMethod(T& t1,T& t2) 
    { 
     static T t; 
     std::cout << "B::someMethod" << std::endl; 
     return t = t1 + t2; 
    } 
}; 

int main() 
{ 
    B<int> b1; 
    b1.A::someMethod("Hi"); 
    // ^^^^^^^^^^^^^^ 
}  

程序输出是

A::someMethod: Hi 

否则,可以通过使用一个宣告的装置包括在派生类的范围的基类的方法的声明。