Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine if a C++ class has a vtable?

Tags:

c++

vtable

A friend of mine sent me the following challenge earlier today:

Given the following code, propose an implementation of OBJECT_HAS_VTABLE so the program prints AnObject has a vtable = 0, AnObjectWithVTable has a vtable = 1.

class AnObject
{
    int m_a;
    void DoSomething() {}

public: 
    AnObject() {m_a = 0;}
};

class AnObjectWithVTable
{
    int m_b;
    virtual void DoStuff() { }

public: 
    AnObjectWithVTable() {m_b = 0;}
};

void main()
{
    printf("AnObject has a vtable = %i, AnObjectWithVTable has a vtable = %i\n",
           OBJECT_HAS_VTABLE(AnObject),
           OBJECT_HAS_VTABLE(AnObjectWithVTable));
}

I've came up with the following solution which I think is decent enough:

template <typename T>
bool objectHasVtable()
{
    class __derived : public T {};
    T t;
    __derived d;

    void *vptrT=*((void **)&t);
    void *vptrDerived=*((void **)&d);

    return vptrT != vptrDerived;
}

#define OBJECT_HAS_VTABLE(T) objectHasVtable<T>()

Is there a better solution to this problem?

Edit

The solution doesn't have to be generic across all compilers. It can work on gcc, g++, MSVC... Just specify for which compiler your solution is known to be valid. Mine is for MSVC 2010.

like image 877
joce Avatar asked May 11 '11 20:05

joce


People also ask

Does every class have a vtable?

So the short answer is no.

What is a vtable in C?

In computer programming, a virtual method table (VMT), virtual function table, virtual call table, dispatch table, vtable, or vftable is a mechanism used in a programming language to support dynamic dispatch (or run-time method binding).

What is vtable and VPTR?

# Vtable is created by compiler at compile time. # VPTR is a hidden pointer created by compiler implicitly. # If base class pointer pointing to a function which is not available in base class then it will generate error over there. # Memory of Vtable and VPTR gets allocated inside the process address space.

What is vtable for base class and derived class?

A virtual table contains one entry for each virtual function that can be called by objects of the class. Each entry in this vTable is simply a Function Pointer that points to the most-derived function accessible by that class ie the most Base Class.


2 Answers

The standard method is to use std::is_polymorphic from C++11/C++03 TR1/Boost to determine if a class (and its bases) contain any virtual members.

#include <type_traits>
#define OBJECT_HAS_VTABLE(T) (std::is_polymorphic<T>::value)
like image 122
kennytm Avatar answered Oct 06 '22 01:10

kennytm


For completeness sake, here's the answer my buddy just sent me. From the look of it, it's probably similar to how TR1 does it (though I haven't looked at the code myself).

template<class T>
class HasVTable
{
public :
    class Derived : public T
    {
        virtual void _force_the_vtable(){}
    };
    enum { Value = (sizeof(T) == sizeof(Derived)) };
};

#define OBJECT_HAS_VTABLE(type) HasVTable<type>::Value
like image 34
joce Avatar answered Oct 06 '22 01:10

joce