rbl
rbl

Reputation: 1

Overloaded functions(virtual/non virtual)

I am having 4 overloaded function vfoo (3 are virtual )

I am trying to test few concepts here:

  1. Overloading using virtual function
  2. Overloaded functions are hidden in derived class when derived class have implemented their own version of overloaded functions.
  3. What is the behavior when a base class pointer stores derived class object
  4. Overloaded functions in derived class like void vfoo( char x )
#include<iostream>
using namespace std;

/*Base class having 4 overloaded function*/  
class ClassBaseV 
{
    public:

        virtual void vfoo( int x ) {
                cout << "ClassBaseV vfoo(int), x = " << x << endl;
        }

        virtual void vfoo( double x ) {
                cout << "ClassBaseV vfoo(double), x = " << x << endl;
        }

        virtual void vfoo( int x, double y ) {
                cout << "ClassBaseV vfoo(int,double), x = " << x << ", y = " << y << endl;
        }

        void vfoo( double x, int y ) {
                cout << "ClassBaseV vfoo(double,int), x = " << x << ", y = " << y << endl;
        }
};


class ClassDerived1 : public ClassBaseV 
{
    public:

        //Overloaded with char x
        void vfoo( char x ) {
                cout << "ClassDerived1 vfoo(char), x = " << x << endl;
        }


         //over riding int x
         void vfoo( int x ) {
                cout << "ClassDerived1 vfoo(int), x = " << x << endl;
        }


};


int main()
{
    ClassBaseV *cB = new ClassDerived1(); /*Base pointer storing derived class object*/
    ClassDerived1 *cd1 = new ClassDerived1(); //Derived class object  
    cd1->vfoo('a');//Direct call using derived class object. this works
    char a = 'a';
    cB->vfoo(a);   // trying to call char x using cB. This calls derived class int How?
    cB->vfoo(10);  // trying to call int x using CB. This calls derived class int 
    cB->vfoo(2.2); // Wanted this to not to work as base class overloaded functions are hidden but this works

    return 1;
}

Upvotes: 0

Views: 1031

Answers (3)

Deduplicator
Deduplicator

Reputation: 45664

If you override part of an overload set in a derived class, it's common practice to get all non-overridden functions into scope with a usingdeclaration. Protects from embarassing failures.

cB->vfoo(a);   // trying to call char x using cB. This calls derived class int How?

Overload resolution in Base gets to nearest match (char -> int) and call using virtual dispatch

cB->vfoo(10);  // trying to call int x using CB. This calls derived class int 

Exact match in overload resolution and virtual dispatch to derived.

cB->vfoo(2.2); // Wanted this to not to work as base class overloaded functions are hidden but

Exact match in overload resolution, virtual dispatch to base.

Never try to remove features in a derived class.

Interface inheritance means: I need at most the guarantees base needs, and my behavior fits the base contract.

Upvotes: 1

naab
naab

Reputation: 1140

FIRST PROBLEM:

cB->vfoo(a);

When you call vfoo here, it tries to find a definition of vfoo(char x) in ClassBaseV, however it doesn't, but still finds a definition of vfoo(int x) which can be implicitly casted to, so it calls this method from ClassBaseV.

The compiler will try to get the definitions of the methods for the class supplied as type.

ClassBaseV *cB = new ClassDerived1();

On this line, you type cB as a pointer to ClassBaseV. From now, the compiler can't lookup method definitions downside (in child classes), but still can do upside, because any possible inheritance to a parent class is known by ClassBaseV.

SECOND PROBLEM:

cB->vfoo(2.2);

On this line, you call the method vfoo(double x ) as the conversion to double is available in the ClassBaseV and you don't override this method in the ClassDerived1.

So it's a normal behaviour that the ClassBaseV implementation of this method is called instead.

If you want to call one of the vfoo overriden in the ClassDerived1, you have to cast it to either int or char (and loose information)

cB->vfoo(static_cast<int>(2.2));

or add a new method in ClassDerived1 overriding the vfoo(double x ) from ClassBaseV.

Also, if you want to force the ClassDerived1 to implement the method vfoo(double x) from ClassBaseV, you have to declare it as pure virtual :

virtual void vfoo( double x ) = 0;

Upvotes: 0

LihO
LihO

Reputation: 42093

"What is the behavior when a base class pointer stores derived class object" - that's the core idea of the polymorphism. Polymorphism is based on the specific behavior based on the type of object determined in run-time while overloaded functions are resolved in compile time.

Type of constant literals can be easily determined at compile time 10 is int, 2.2 is double, this will determine which member function will be used. The type of the instance will then determine which implementation will be used (which class). Here's simpler example:

class Animal {
public:
    virtual void makeSound(){ std::cout << "hi" << std::endl; }
    virtual void makeSound(int pain){ std::cout << "ouch" << std::endl; }
    virtual void makeSound(double d){ std::cout << "aaaaaaaargh" << std::endl; }
};

class Cat : public Animal {
public:
    virtual void makeSound(){ std::cout << "meow" << std::endl; }
    virtual void makeSound(int pain){ std::cout << "MEEEEEOW!!!" << std::endl; }
    virtual void makeSound(double d){ std::cout << "meow double" << std::endl; }
};

int main() {
    Animal *a = new Animal();
    Animal *cat = new Cat();
    a->makeSound();
    cat->makeSound();
    a->makeSound(100);
    cat->makeSound(100);
    cat->makeSound(750.80);
}

outputs:

hi
meow
ouch
MEEEEEOW!!!
meow double

Upvotes: 0

Related Questions