c++ issue with function overloading in an inherited class
Asked Answered
P

5

62

This is possibly a noob question, sorry about that. I faced with a weird issue recently when trying to mess around with some high level stuff in c++, function overloading and inheritance.

I'll show a simple example, just to demonstrate the problem;

There are two classes, classA and classB, as below;

class classA{
    public:
        void func(char[]){};    
};

class classB:public classA{ 
    public:
        void func(int){};
};

According to what i know classB should now posses two func(..) functions, overloaded due to different arguments.

But when trying this in the main method;

int main(){
    int a;
    char b[20];
    classB objB;
    objB.func(a);    //this one is fine
    objB.func(b);    //here's the problem!
    return 0;
}

It gives errors as the method void func(char[]){}; which is in the super class, classA, is not visible int the derived class, classB.

How can I overcome this? isn't this how overloading works in c++? I'm new to c++ but in Java, i know I can make use of something like this.

Though I've already found this thread which asks about a similar issues, I think the two cases are different.

Penitential answered 8/1, 2013 at 9:47 Comment(0)
P
82

All you need is a using:

class classB:public classA{ 
    public:
        using classA::func;
        void func(int){};
};

It doesn't search the base class for func because it already found one in the derived class. The using statement brings the other overload into the same scope so that it can participate in overload resolution.

Pallua answered 8/1, 2013 at 9:49 Comment(2)
Is there any better alternative(s) in 2020 now?Mascot
@Raining, No, and I consider it unlikely that there will be. I'm not sure what kind of alternative you mean rather than changing name lookup, which isn't an attractive prospect. You could, if you can even call this an alternative, provide all the overloads in base classes and bring them into scope all at once. Such a technique can be useful when used in a variadic template. Beyond that, it's hard to say at such a general level—maybe something new is useful in a narrower context. Perhaps you could consider composition over inheritance to be a general alternative.Pallua
C
12

It is well explained for example in this question's answers:

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

In short, compiler will stop searching for matching methods from parent classes, when it finds matching method name in current class, even when that method is not compatible. I guess this allows some automatic type conversions to work more logically, without needing to override so many parent class methods.

Cankerworm answered 8/1, 2013 at 9:53 Comment(2)
Thanks for the answer+link. i wonder whether c++ people kept this thing intentionally. are there any pros? it feel like to me that spoil the idea of inheritance, isn't it?Penitential
@Sumudu: I can give you a absolute correct idea about this, also I think you don't care anymore 7 years later: (From language specification) It's because we don't want the change of base class to influence the derived class.Mascot
S
3

If you override one variant of a function in the derived class, you need to override all variants. You can either use what JLledo suggested or write the variant of the function in the derived class which simply calls the base class's function of same signature.

class classA{
    public:
        void func(char[]){};    
};

class classB:public classA{ 
    public:
        void func(int){};
        void func(char[]){};
};

void classB:func(char[] ch)
{
    classA::func(ch);
}
Suckle answered 10/1, 2013 at 2:55 Comment(0)
B
1

The solution proposed provides a maintenance headache. Injecting a using A::func into a derived class requires that rearchitecting software be sensitive to using clauses placed in derived classes, that is, rather than changing a base class by itself the maintainer has to also change a derived class. Suppose we go from base<-derived1 to base<-derived2<-derived1. Now a using clause, using base::func must be changed to using derived2::func, forcing consideration of using clauses and increasing the cost of maintenance. Saying that this has been in the C++ standardizing effort for quite some time doesn't change that the idea seems ill-conceived. It interrupts the notion of inheritance. Just my thought on this.

Bisitun answered 1/8, 2021 at 16:8 Comment(0)
E
-5

You must pass the argument of type int in

objB.func(b);    //here's the problem!

bcs it has been overloaded with int argument

Edirne answered 13/2, 2014 at 8:51 Comment(1)
You may try and provide a more detailed answer.Myotome

© 2022 - 2024 — McMap. All rights reserved.