Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't the virtual function table pointer (vfptr) be static in C++?

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?

like image 741
sn710 Avatar asked Aug 23 '14 16:08

sn710


People also ask

Why is VPTR not static?

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.

Is virtual table static?

The vtable is essentially static. But you need a vptr member actually inside the object to do virtual dispatch and other RTTI operations.

Can virtual functions be dynamic and static?

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.

Why is a pointer required for virtual function?

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.


1 Answers

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 };
like image 87
aschepler Avatar answered Sep 18 '22 09:09

aschepler