Matimath
Matimath

Reputation: 31

cpp polymorphism and inheritance - compiler does not see method

I have two classes:

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

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

My problem is that know I can't call

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

because my compiler can't see someMethod(std::string). Do you know why it is so?

Upvotes: 1

Views: 80

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 310920

The problem is that a method in a derived class hides all methods of the base class with the same name.

To call the base class method you have to use a qualified name.

For example

#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" );
    // ^^^^^^^^^^^^^^
}    

The program output is

A::someMethod: Hi

Otherwise you can include the declaration of the base class method in the scope of a derived class by means of a using declaration.

Upvotes: 0

AProgrammer
AProgrammer

Reputation: 52274

Do you know why it is so?

Yes.


During a name look up in a scope, the search for definitions stop going from included to enclosing scope when a scope has definitions for the names. And class inheritance is considered as nesting scope (with some caveats irrelevant to the current discussion to handle multiple inheritance). Thus when the B definition of someMethod is found, the search stop and A is not looked in. ForEveR gave the way to import the definitions of A into B with using.

Note that the search algorithm is a general rule and applies to other kind of nested scopes, blocks (but declaration of functions of blocks is not something done often nowadays) and namespace (try defining overloaded functions ns1::someFunction and ns2::someFunction, in ns2 you won't be able to call ns1::someFunction if you don't import its declaration).

Upvotes: 0

ForEveR
ForEveR

Reputation: 55887

Yes, it's name hiding. You should just add using declaration.

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

Upvotes: 7

Related Questions