Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading a method in a subclass in C++

Suppose I have some code like this:

class Base {
    public:
      virtual int Foo(int) = 0;
};

class Derived : public Base {
    public:
      int Foo(int);
      virtual double Foo(double) = 0;
};

class Concrete : public Derived {
    public:          
      double Foo(double);
};

If I have a object of type Concrete, why can I not call Foo(int)?
If I change the name of Foo(double) so that it isn't overloading Foo, then all is well and both methods are accessible, but this isn't what I want.
Similarly, if I remove Concrete class and implement Foo(double) in Derived, then both are accessible, but again, not what I want.

like image 671
James Avatar asked Nov 14 '09 17:11

James


People also ask

Can you overload a method in a subclass?

Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass.

Can you overload a method in the same class?

In other words, we can say that Method overloading is a concept of Java in which we can create multiple methods of the same name in the same class, and all methods work in different ways. When more than one method of the same name is created in a Class, this type of method is called the Overloaded Method.

Can method overloading be done in C?

This feature is present in most of the Object Oriented Languages such as C++ and Java. But C doesn't support this feature not because of OOP, but rather because the compiler doesn't support it (except you can use _Generic).

Can overloading be done in inheritance?

Method overloading can be achieved by changing the number of parameters while passing to different methods.


2 Answers

Name lookup happens before overload resolution, so once Foo has been found in Concrete, base classes won't be search for other methods called Foo. int Foo(int) in Derived is hidden by the Foo in Concrete.

You have a number of options.

Change the call to be explicit.

concrete.Derived::Foo(an_int);

Add a using declaration to Concrete.

class Concrete : public Derived {
public:          
   using Derived::Foo;
   double Foo(double);
};

Call the function through a base reference.

Derived& dref = concrete;
dref.Foo(an_int);
like image 188
CB Bailey Avatar answered Nov 13 '22 16:11

CB Bailey


Foo(double) hides the function from your base. You can make it visible though:

class Concrete : public Derived 
{
public:          
  using Derived::Foo;
  double Foo(double);
};
like image 36
Georg Fritzsche Avatar answered Nov 13 '22 17:11

Georg Fritzsche