如何确定C++类是否有vtable?

joc*_*oce 10 c++ vtable

我的一位朋友今天早些时候向我发出了以下挑战:

鉴于以下代码,建议执行OBJECT_HAS_VTABLE程序打印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));
}
Run Code Online (Sandbox Code Playgroud)

我想出了以下解决方案,我认为这个解决方案足够好了:

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>()
Run Code Online (Sandbox Code Playgroud)

你们可以为这个问题提出更好的解决方案吗?

请享用!:-)

编辑

该解决方案不必在所有编译器中都是通用的.它可以在gcc,g ++,MSVC上工作......只需指定您的解决方案已知哪个编译器有效.我的是MSVC 2010.

ken*_*ytm 17

标准的方法是使用std::is_polymorphic升压/TR1,以确定是否一个类(及其碱基)含有任何虚拟成员.

#include <type_traits>
#define OBJECT_HAS_VTABLE(T) (std::is_polymorphic<T>::value)
Run Code Online (Sandbox Code Playgroud)

  • @unapersson:type_traits是TR1的一部分,然后是C++ 0x.后两个*是*标准. (4认同)
  • 根据标准,这个答案是不准确的,`std :: is_polymorphic`只能**检测虚拟函数**,但是**没有虚拟函数的虚拟继承也将生成vtable **,至少对于GCC 4.8而言。 5 (2认同)

joc*_*oce 9

为了完整起见,这是我哥们给我的答案.从它的外观来看,它可能类似于TR1的工作原理(虽然我自己没有看过代码).

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
Run Code Online (Sandbox Code Playgroud)