6

I've found a strange behavior while using a reference variable.

Here is class implementations:

class Base {
    public:
        virtual void Method() = 0;
};

class DerivedA : public Base {
    public:
        virtual void Method() {}
}

class DerivedB : public Base {
    public:
        virtual void Method() {}
}

Here is an example code which have the strange behavior:

void main(int argc, char *argv[]) {
    DerivedA a;
    DerivedB b;
    Base &base = a;

    base.Method();   // Calls DerivedA::Method

    base = b;
    base.Method();   // Calls DerivedA::Method!!! Why doesn't call DerivedB.Method()?
}

In conclusion, it seems that the virtual function pointer table "associated" to the reference variable is determine only when initializing the reference variable. If I re-assign the reference variable the vfpt doesn't change.

What happens here?

Luca
  • 11,646
  • 11
  • 70
  • 125

2 Answers2

13

Base &base is a reference, i.e. alias to the a object, so the assignment base = b is equivalent to a = b, which leaves the base thingie still the same object of the same class. It is not a reassignment of pointer as you seem to assume.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
7

References can only be initialized once. You can not assign a new object to a reference. What is actually happening here is that operator= of Base is called and the underlying object is still DerivedA and not DerivedB.

selalerer
  • 3,766
  • 2
  • 23
  • 33
  • I am not sure this is correct actually. The operator= is not defined in Base, so there is nothing to call really, apart from C++ default implementation of operator=. I think what is happening here is what @MichaelKrelin answered below. – Rafid Nov 24 '13 at 11:39
  • @Rafid As you wrote, there's the default implementation of operator=. The default implementation is not virtual and the type of base is Base so Base::operator=() is called. Michael answer is correct too. The two answers do not contradict each other. – selalerer Nov 24 '13 at 12:41
  • This answer contradicts neither my answer nor the truth. The only thing that bothers me is how is it important that the default `operator=` implementation is not virtual? ;-) – Michael Krelin - hacker Nov 24 '13 at 15:50
  • @MichaelKrelin-hacker Just noting that which operator is to be called is dependent only on the type of the reference and not dependent on the type of the object. – selalerer Nov 24 '13 at 16:59
  • Yeah, though was it to depend on the type of the reference it still would be `a`'s `operator=` ;-) – Michael Krelin - hacker Nov 24 '13 at 19:05