Reputation: 1
I am having 4 overloaded function vfoo
(3 are virtual )
I am trying to test few concepts here:
#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
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 using
declaration. 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
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
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