I have a base class pointer pointing to a derived class object. I am calling foo()
function by using two different ways in the code below. Why does Derived::foo()
get called in the first case? Shouldn't (*obj).foo()
call Base::foo()
function as it has already been dereferenced?
class Base
{
public:
Base() {}
virtual void foo() { std::cout << "Base::foo() called" << std::endl; }
virtual ~Base() {};
};
class Derived: public Base
{
public:
Derived() : Base() {}
virtual void foo() { std::cout << "Derived::foo() called" << std::endl; }
virtual ~Derived() {};
};
int main() {
Base* obj = new Derived();
// SCENARIO 1
(*obj).foo();
// SCENARIO 2
Base obj1 = *obj;
obj1.foo();
return 0;
}
// SCENARIO 1 (*obj).foo();
Note that
obj
is a misnomer here, since it doesn't refer to an object, but to a pointer, (*ptr).foo()
is just a roundabout way to do ptr->foo()
. *ptr
doesn't result in an object, but in a reference Base&
to the object. And a virtual function call through a reference is subject to dynamic dispatch, just as such a call through a pointer.
// SCENARIO 2 Base obj1 = *ptr; obj1.foo();
What you do here is you create a totally new object through slicing: it just has the base class parts of *ptr
. What you want instead is this:
Base& ref = *ptr;
ref.foo();
Scenario 2 creates an entirely new object of type Base. As such, when we do obj1.foo()
, the object isn't Derived at all; there's no way we'll call the Derived function.
In scenario 1, however, the object is, in truth, an instance of Derived, which we're accessing through a Base pointer. This is exactly the situation virtual functions are designed for; the derived class's implementation is used.
It helps if you think a little bit about the implementation. In the second scenario you're actually creating a new object of type Base which will come with a new virtual function table. But in the first scenario *obj
will "point to", or rather reference, an object which still has the virtual function table of an object of type Derived.
As an addition to other answers.
The technical term for what is happening in your Scenario 2 is object slicing.
Here's the wikipedia entry:
http://en.wikipedia.org/wiki/Object_slicing
And here's another question on stackoverflow on object slicing:
What is object slicing?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With