Why should I use the "using" keyword to access my base class method?
Asked Answered
W

5

80

I wrote the below code in order to explain my issue. If I comment the line 11 (with the keyword "using"), the compiler does not compile the file and displays this error: invalid conversion from 'char' to 'const char*'. It seems to not see the method void action(char) of the Parent class in the Son class.

Why the compiler behave this way? Or have I done something wrong?

class Parent
{
    public:
        virtual void action( const char how ){ this->action( &how ); }
        virtual void action( const char * how ) = 0;
};

class Son : public Parent
{
    public:
        using Parent::action; // Why should i write this line?
        void action( const char * how ){ printf( "Action: %c\n", *how ); }
};

int main( int argc, char** argv )
{
    Son s = Son();
    s.action( 'a' );
    return 0;
}
Whizbang answered 13/12, 2009 at 15:32 Comment(5)
Please tell me: what if you remove const in "const char how"?Bickford
You don't need to type Son s = Son();. That just creates a temporary and then calls the copy constructor. Just type Son s;Clayborn
We get this question a LOT: http://stackoverflow.com/questions/1835988 http://stackoverflow.com/questions/411103 http://stackoverflow.com/questions/1480085 http://stackoverflow.com/questions/1799497 http://stackoverflow.com/questions/888235 http://stackoverflow.com/questions/72010Kinesiology
Why is C++ designed like that version: #4837899Harpp
No need for unreadable using ..., do this->action(...) just like new languages (i.e. type-script, which forces developers to write "this" to avoid mistakes).Greyson
W
66

The action declared in the derived class hides the action declared in the base class. If you use action on a Son object the compiler will search in the methods declared in Son, find one called action, and use that. It won't go on to search in the base class's methods, since it already found a matching name.

Then that method doesn't match the parameters of the call and you get an error.

See also the C++ FAQ for more explanations on this topic.

Wince answered 13/12, 2009 at 15:45 Comment(3)
@Wince Good to know that. but is this, may i say, a feature of c++ or some kind of a bug? doesn't this spoil the whole idea of inheritance? just asking..Piatt
Is the name matching done using the mangled name, does method overloading play a role here, or is the first function called that has the name "action" and that's it?Cadet
@Anubis: The rule simplifies name lookup. Without it, the compiler would need to walk over the complete inheritance tree when it needs to resolve the name of a member function (there could be overloads of the function in some base class). With the rule, the compiler can stop looking at the rest of the inheritance tree once it found a class containing a fitting name. The programmer is in the same situation. Looking at the derived class he can be sure that the function defined there will be called, without having to know if some base class might contain a different function of the same name.Wince
O
21

Surprisingly this is standard behavior. If a derived class declares a method with the same name as a method defined by the base class, the derived class' method hides the base class' one.

See C++ FAQ

Oina answered 13/12, 2009 at 15:44 Comment(0)
S
6

A note of caution: The need to use a "using" in this situation is a red flag that your code may be confusing for other developers (after all it confused the compiler!). It is likely that you should rename one of the two methods to make the distinction clear to other programmers.

One possibility:

void action( const char how )
{ 
  takeAction( &how ); 
}
void action( const char * how )
{
  takeAction(how);
}
virtual void takeAction(const char * how) = 0;
Sewer answered 23/1, 2013 at 22:22 Comment(0)
R
6

If in a derived class any over loaded function is redefined then all the overloaded function in the base class is hidden. One way to include both the functionality is to avoid function overloading in classes. or You can use using keyword, as used.

Redfield answered 7/10, 2014 at 10:37 Comment(1)
I have a base class with large number of methods, writing using base::method for each method is tedious. Is there a way to do this using single using declaration ,?Kuopio
A
0

By using using, the names declared in base class are introduced into the namespace of derived class.

Then, when you declare the set of functions in the derived class, they are distinguished from those with identical parameter types in its base class by compilers by the type of the implicit this pointer.

During overload resolution, an argument that needs a class-type conversion, which will happen when a pointer to derived class is converted to a pointer to a base class, is of the lowest priority.

So the two functions with seemingly identical parameter list can be distinguished, and when calling them from an object of the derived type, the one locally declared will be a better (if not exact) match.

I am a newbie and please point out my misunderstanding.

Antipode answered 24/8, 2021 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.