My question is basePtr itself is of type Base. How is it able to access the vptr which is present inside the Derived class?
It's not, it's only accessing its own vptr, but that vptr is being modified by Derived during initialization. In C++ inheritance, the base class is contained in the derived class as a base class subobject.
The layout is as follows:
class Base {
protected:
vtable_t* vptr;
public:
// ...
};
class Derived {
public:
Base BaseSubobject;
// ...
};
// probably passes, if a vtable pointer is as large as void*
static_assert(sizeof(Base) == sizeof(void*));
// will pass on any sane implementation
static_assert(sizeof(Derived) == sizeof(Base));
Notice that Derived doesn't have its own vptr, there only one vptr inside of the BaseSubobject.
During When Derived gets initialized, it will first initialize the BaseSubobject inside, and then mutate the vptr inside of Base to become a pointer to the Derived vtable. The process looks something like this:
// Base constructor sets its vptr to the vtable of Base
Base::Base() : vptr(&Base::vtable) {}
// Derived constructor first initializes Base, then replaces the vptr inside
Derived::Derived() : BaseSubobject() {
// replaces Base::vptr
this->BaseSubobject.vptr = &Derived::vtable;
}
// dynamic dispatch process for virtual void foo():
void Base::__dispatch_to_foo__() {
// step 1: fetch address of virtual function from Base::vptr,
// which may be a pointer to Derived::vtable
void(*foo)(Base*) = this->vptr[__foo_index__];
// step 2: call the fetched address
foo(this);
}
On a side note, this is also why virtual calls won't dispatch to Derived in the Base constructor. While Base is being initialized, its vtable pointer hasn't been replaced by that of Derived yet.
Disclaimer 1: All uses of types, data members, and constructors are exposition-only. They're just meant to approximate what the compiler generates, and are not equivalent.
Disclaimer 2: vtables are an implementation detail. The C++ standard doesn't require polymorphism to be implemented this way, but most compilers use this technique.