Reputation: 11
I have following code snippet:
class base
{
public:
virtual void print(char a){ std::cout << " Base\n"; }
};
class derived : public base
{
public:
void print(float a) { std::cout << " Derived\n"; }
};
int main() {
base* d = new derived;
d->print(1.5);
}
Output is Base
.
Why is the output coming from the base function and not from the derived one?
Upvotes: 1
Views: 1745
Reputation: 56875
When you declare Base* d = new Derived;
, the type of the class is Base, as printed by typeid(d).name()
, so this instance doesn't have access to child class methods. If you change the type to Derived, you'll call the child method:
#include <iostream>
#include <typeinfo>
class Base
{
public:
virtual void print(char a) {
std::cout << " Base " << std::endl;
}
};
class Derived : public Base
{
public:
void print(float a) {
std::cout << " Derived " << std::endl;
}
};
int main()
{
Derived* d = new Derived;
std::cout << "class type is: " << typeid(d).name() << std::endl;
d->print(1.5);
return 0;
}
Output:
class type is: P7Derived
Derived
Furthermore, declaring the parent class print
method virtual
doesn't allow an instance of Base to call the child version of print
because the child hasn't overridden it (different headers). Creating an instance of Base with Base *d = new Derived;
and changing the Derived print
method header to void print(char a)
in the Derived class would allow you to call the child print
method and output Derived
, even from an instance of Base, using the virtual
keyword.
#include <iostream>
#include <typeinfo>
class Base
{
public:
virtual void print(char a) {
std::cout << " Base " << std::endl;
}
};
class Derived : public Base
{
public:
void print(char a) {
std::cout << " Derived " << std::endl;
}
};
int main()
{
Base* d = new Derived;
std::cout << "class type is: " << typeid(d).name() << std::endl;
d->print(1.5);
return 0;
}
Output:
class type is: P4Base
Derived
Upvotes: 1
Reputation: 40604
You have not overridden the function in the base class, you have overloaded it: The version in the derived class takes a float
as an argument, and is quite a different beast from the base class method which takes a char
. Moreover, the float
version in the derived class shadows the base class version: The base class version becomes inaccessible for calls on the derived type.
As such, the following code
Derived d;
d.print('a');
d.print(1.5);
will print
Derived
Derived
because the call is resolved by the compiler to the only version of print()
that's available in Derived
.
Likewise, when you call d->print(1.5)
through a pointer to Base
, the derived class' version is inaccessible to the call: The compiler looks at the base class, sees that there is no print()
method defined with a float
argument, and converts the argument to char
instead. It then calls the only implementation of print(char)
, which happens to be supplied by the base class.
If you simply change the signature of the print()
method in the derived class to match that of the base class, the odd behavior will go away.
Upvotes: 1