我的一位朋友今天早些时候向我发出了以下挑战:
鉴于以下代码,建议执行
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)
为了完整起见,这是我哥们给我的答案.从它的外观来看,它可能类似于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)