5

Method func from DerivedClass override the method func and all its overloads from BaseClass.

#include <cstdio>

class BaseClass
{
    public:
        void func(int a){puts("BaseClass::func(int)");};
        void func(int a, int b){puts("BaseClass::func(int, int)");};
        void func(int a, int b, int c){puts("BaseClass::func(int, int, int)");};
        //...
};

class DerivedClass : public BaseClass
{
    public:        
        void func(int a){puts("DerivedClass::func(int)");}
        //...             
};

int main()
{           
    DerivedClass obj;
    obj.func(0);
    obj.func(0, 0);     // error
    obj.func(0, 0, 0);  // error      

    return 0;
}

How can I fix this code to end up on the screen was derived:

DerivedClass::func(int)
BaseClass::func(int, int)
BaseClass::func(int, int, int)

Edit 1 In functions main should not change anything

Amazing User
  • 3,473
  • 10
  • 36
  • 75

2 Answers2

5

The derived class's member function doesn't override the base class ones, it hides them. To bring them all to scope, use a using declaration:

class DerivedClass : public BaseClass
{
    public:        
        void func(int a){puts("DerivedClass::func(int)");}
        using BaseClass::func;
        //...             
};

Live example

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
2

It's by design: the phenomenon is called "name hiding".

[Short answer]:

C++ doesn't like the idea that a long-standing behavior as calling one base-function with a specific set of parameters can be modified in one of your subclasses and chose to hide all overloads in every base class to solve this.

[Long answer] here: https://stackoverflow.com/a/1629074/1938163


As a workaround you can cast the object to the appropriate base and call the functions you need (there's a cast penalty though), or better call the function you need directly by specifying its base class

int main()
{           
    DerivedClass obj;
    obj.func(0);
    obj.BaseClass::func(0,0);

    return 0;
}

Live Example

or you can un-hide them with a "using directive"

class DerivedClass : public BaseClass
{
    public:        
        void func(int a){puts("DerivedClass::func(int)");}
        using BaseClass::func;
        //...             
};

Live Example

Community
  • 1
  • 1
Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • `dynamic_cast` is not needed. Can do the same with `obj.BaseClass::func(0,0);`. Besides, the question was how to design the two classes so that `func` can be called directly on `obj`. – iavr Feb 18 '14 at 21:18