1

I have the following code:

#include <iostream>
using namespace std;

class Parent {
public:
    virtual void f() { cout << "Parent" << endl; }
};

class Child : public Parent {
public:
    void f() { cout << "Child" << endl; }
};

void t1(Parent * p) { p->f(); }
void t2(Parent & p) { p.f(); }

int main() {
    Child a;

    t1(&a);
    t2(a);

    return 0;
}

I tested this both in Visual Studio 2013 and ideone.com, and both got the result:

Child
Child

I can understand t1 calling Child::f() as the result of dynamic binding, but the second one has me puzzled - I expected the Parent & to "fix" the type, so t2 would call Parent::f(). Am I misunderstanding the rules? How does one explain this behavior?

Arun A S
  • 6,421
  • 4
  • 29
  • 43
martin_ljchan
  • 1,063
  • 1
  • 9
  • 22

1 Answers1

3

This is what polymorphism does.


I expected the Parent & to "fix" the type, so t2 would call Parent::f().

Well, you expected wrong.

Am I misunderstanding the rules?

Yes.

How does one explain this behavior?

By picking up a book on C++ and reading the chapter on polymorphism.
Your Parent& works just as a Parent* would: by allowing virtual dispatch.

The important thing to note is that pointers (and references) do not invoke polymorphism. So wherever you read that only pointers invoke polymorphism was doubly wrong. Polymorphism is invoked by object access. It just so happens that, due to the slicing problem, it is impossible to invoke virtual dispatch except through a pointer or reference.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • On [invoking](https://stackoverflow.com/questions/15188894/why-doesnt-polymorphism-work-without-pointers-references) virtual dispatch – edmz May 03 '15 at 18:30
  • I must have somehow missed the part about virtual dispatch works for pointers _and references_. Thanks everyone for the help; the extra reading is also appreciated :) – martin_ljchan May 03 '15 at 18:42