I’m slightly ashamed to admit that I just made a discovery about C++ classes that I probably should have realised years ago.

If you have something like


class A {

  public:

    virtual void fn() { cout << "I'm A" << endl;} ;

} ;



class B : public A {

  public:

    void fn() { cout << "I'm B" << endl ;} ;

} ;



void callfn(A a){

  a.fn() ;

}

it doesn’t do what I expected at all…

For instance, consider the code


  A a; B b;

  callfn(a) ; callfn (b) ;

This compiles just fine – but the output is




I'm A

I'm A

!!!!

In fact, you need to be using pointers to get the behaviour I was after


void callfn(A *a){

  a->fn() ;

}



 ...



  A a; B b;

  callfn(&a) ; callfn (&b) ;

This exhibits the behaviour I was looking for, namely:


I'm A

I'm B

It’s probably very obvious why this is the case, but it stumped me for a bit.