If the virtual function table is the same for all objects of the class, then why can't the pointer to that table (vfptr) be static and be shared across all the objects?
If that vptr is static then Oc's vtable entry will still be pointing to Base's destructor and only base part of Oc is destroyed. Oc's vptr should always point to most derived object's destructor, which is not possible if vptr is static.
The vtable is essentially static. But you need a vptr member actually inside the object to do virtual dispatch and other RTTI operations.
A virtual function cannot be global or static because, by definition, a virtual function is a member function of a base class and relies on a specific object to determine which implementation of the function is called.
Because if you pass by value, then object slicing will occur, and runtime polymorphism cannot be achieved. And in your code, the very line Material m = Texture() causes object slicing. So even if you pass m by pointer (or reference), runtime polymorphism cannot be achieved.
The vtable is essentially static. But you need a vptr member actually inside the object to do virtual dispatch and other RTTI operations.
On a vptr implementation, this C++ code:
class Base {
public:
virtual void f();
};
class Derived : public Base {
public:
virtual void f();
};
may act similarly to something like this:
class Base {
public:
Base::Base() : m_vptr(&Base_vtab) {}
Base::Base(const Base& b) : m_vptr(&Base_vtab) {}
void f() { (m_vptr->f_impl)(this); }
protected:
struct VTable {
void (*f_impl)(Base* self);
};
const VTable* m_vptr;
static const VTable Base_vtab;
private:
static void Base_f(Base* self);
};
const Base::VTable Base::Base_vtab = { &Base::Base_f };
class Derived : public Base {
public:
Derived::Derived() : Base() { m_vtpr = &Derived_vtab; }
Derived::Derived(const Derived& d) : Base(d) { m_vptr = &Derived_vtab; }
Derived::~Derived() { m_vptr = &Base::Base_vtab; }
protected:
static const VTable Derived_vtab;
private:
static void Derived_f(Derived* self);
static void Derived_f(Base* self) { Derived_f(static_cast<Derived*>(self)); }
};
const Base::VTable Derived::Derived_vtab = { &Derived::Derived_f };
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