c++virtual

Virtual tables when copying objects


#include <iostream>
#include <string>
class A
{
public:
    A(int a) : _a(a) {}
    virtual ~A() {}
    virtual void f() const {std::cout << _a << std::endl;}
private:
    int _a;
};
class B : public A
{
public:
    B(int a, int b) : A(a), _b(b) {}
    virtual void f() const {std::cout << _b << std::endl;}
private:
    int _b;
};
int main()
{
    B b (1,2);
    A a (5);
    A& ref = a;
    ref = b;
    ref.f();
    return 0;
}

Output:

1

I understand that when copying derived (extended) class object to the base class object, the derived object is being cut and only the base class data copied. But i thought that the virtual table of 'ref' now should be as a virtual table of 'b' so 'ref.f();' should call the function:

void B::f() const {std::cout << _b << std::endl;}

But after the copying the vtbl of 'ref' remains to be the vtbl of class A. why? Thanks.


Solution

  • Firstly 'virtual table' is not a standard C++ concept. It is a highly implementation specific mechanism to implement dynamic binding and implement virtual functions.

    Having said that,

    But i thought that the virtual table of 'ref' now should be as a virtual table of 'b' so 'ref.f();' should call the function

    This is not correct. Virtual table is per class and not per object. It is only Vptr that is per object.

    The type of 'ref' (as confirmed by typeid(ref).name if you so please) is 'A &'. When you assign 'ref = b' the implicit assigment operator of 'A' is called with object 'b' as the argument. This operator just blindly copies the 'A' subobject of 'b' into the current object referenced by 'ref' (which is 'a'). Hence object 'a' now has the exact same state as the 'A' subobject of 'b'.

    As you can see, in this whole very long story, VTABLE and VPTR does not exist at all!.