Reputation: 1146
I have a doubt regarding upcasting. Consider there are two classes, Class Parent and Class child. Child has inherited with parent.
Question:
If i create object pointer for parent, and assigned child object reference. I complied it. the output is "object slicing". Couldn't access the child class specific components
class Parent
{
public:
int i;
void school()
{
std::cout<<"Parent Class::School()"<<std::endl;
}
// virtual goToPlay()
// {
// std::cout<<"Parent Class::goToPlay()"<<std::endl;
// }
};
class Child:public Parent
{
public:
int j;
void goToPlay()
{
std::cout<<"Child Class::goToPlay()"<<std::endl;
}
};
int main()
{
Parent *mParent;
Child mChild;
mParent = &mChild;
mParent->school();
mParent->goToPlay(); //Error
couldnt access goToPlay() API. If i create a virtual function of goToPlay() in Parent Class, then its is accessible. Can any one tell whats the reason?
Upvotes: 1
Views: 1162
Reputation: 385284
In order to use Child::goToPlay()
through a pointer-to-Parent
, Parent
would have to declare its own function goToPlay()
, and this function would have to be marked virtual
. Your Child
class then overrides that function.
Then, when you call goToPlay()
on the Parent
pointer, the Child
function is magically invoked instead.
However, you can't just do this for arbitrary functions that doesn't even exist in Parent
.
Upvotes: 1
Reputation: 8975
You explicitly declare Parent * mParent
, so your object is treated as an instance of Parent
. In many use cases, this is exactly what you want - you provide a proper interface for doing something, and the concretely used implementation is of no concern to the end user:
class employee
{
public:
virtual double get_salary_in_usd() const = 0;
virtual ~employee() {}
};
class software_developer : public employee
{
public:
double get_salary_in_usd() const { return 100000.; /* i wish */ }
void be_awesome() {}
~software_developer() {}
};
void print_salary(std::shared_ptr<employee> const & emp)
{
std::cout << "This employee earns $" << emp->get_salary_in_usd()
<< " a month." << '\n';
}
In some cases however, you need to tell at runtime, whether your pointer is a certain child of your base class. This is what dynamic_cast
is for:
software_developer me;
employee * me_generalized = &me;
software_developer * me_again = dynamic_cast<software_developer *>(
me_generalized);
if(me_again != nullptr)
{
me_again->be_awesome();
}
Note that dynamic_cast
can return nullptr
if the pointer could not be casted. Also note that this happens with RTTI during runtime, and slows down your application. Avoid using this whenever possible.
Upvotes: 1
Reputation: 13713
Since your pointer type is Parent
then only the Parent's api will be accessible since that is what you tell the compiler. (i.e. this pointer points to a Parent
object).
In your case a virtual
method will make the correct implementation being called. (this is called late binding and it is done during run time via hidden tables in the instance to find the correct address of the method's implementation which in your case is the Child
implementation since mParent
points to a Child
instance)
Upvotes: 1