3

After upcasting a derived class's pointer, a virtual method of the derived class is still called, which seems to me wrong, as slicing should have happened. Could you please comment what's wrong with this code?

class Base
{
public:
    virtual void Hello() { cout << "Hello Base" << endl; }
};

class Derived: public Base
{
public:
    void Hello() { cout << "Hello Derived" << endl; }
};

int main()
{
    Derived* der = new Derived;
    Base* base = dynamic_cast<Base*> (der);
    if (base) base->Hello();
}

output: Hello Derived

rightaway717
  • 2,631
  • 3
  • 29
  • 43
  • 1
    If it didn't polymorphism would not work. Not having to know the dynamic type (and it still being dispatched) is kind of the point here. – Thilo Sep 06 '12 at 04:54
  • The dynamic cast is pointless here, since `Base` is a non-virtual *base* class. But anyway, if you want to call the base function, you can say `der->Base::Hello();`. – Kerrek SB Sep 06 '12 at 05:01

2 Answers2

4

Slicing did not happen because you didn't work with any values of Base, just pointers to it.

This would cause slicing:

Base base = *der;

But if you want to call a function and suppress dynamic dispatch, you can just do this:

base->Base::Hello();

The function to call is specified statically. This works with der too, of course, avoiding the middle-man.


Your dynamic_cast is not needed here. You can implicitly upcast, because this is trivially verifiable at compile-time. You can use static_cast to downcast, but it's up to you to make sure this is actually correct; dynamic_cast is just a checked version of that.

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • Thank you for pointing out when slicing happens. I misunderestood that and though it happened every time I worked with base class pointers and objects no matter what they actually were – rightaway717 Sep 06 '12 at 05:17
2

Pointer casting is about the static type system, which is safety at compile time. E.g. casting is telling the compiler "trust me". It has no bearing at runtime. The nicer cast operations, like dynamic_cast provide some runtime checks (don't do this unless it makes sense), but that still does not affect the polymorphism, it just is a more qualified "trust me"...trust me unless I do something insane.

Polymorphism is about doing the right thing at runtime. When you call a virtual method through a pointer, it will run do the correct operation for the object instance.

In C++, you can ask for a specific resolution using the :: operator, but that is typically reserved for implementation details.

Tony K.
  • 5,535
  • 23
  • 27
  • Does this mean that using static_cast here will help? Because I tried and it didn't work. Still the derived class's method was called. So as far as I got if I want to call a base class method, I have the only way to do it - via :: operator? – rightaway717 Sep 06 '12 at 05:05
  • Right, the :: is your only choice – Tony K. Sep 06 '12 at 15:10