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 printsAnObject 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.
So the short answer is no.
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).
# 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.
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.
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)
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
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