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?
A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.
For every class that contains virtual functions, the compiler constructs a virtual table, a.k.a vtable. The vtable contains an entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function definition callable by the class is stored in the vtable.
Virtual functions are invoked when you have a pointer or reference to an instance of a class. Static functions aren't tied to the instance of a class but they are tied to the class. C++ doesn't have pointers-to-class, so there is no scenario in which you could invoke a static function virtually.
Non- virtual member functions are resolved statically. That is, the member function is selected statically (at compile-time) based on the type of the pointer (or reference) to the object. In contrast, virtual member functions are resolved dynamically (at run-time).
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.
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.
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