Impossible, you cry: POD is POD and virtual functions are virtual functions and nary the twain shall meet! More sophisticated readers among you might assume this is a rehash of static polymorphism, but this is not so. I have a POD struct that can be used nonhomegenously in a container, and support run-time polymorphism. Without further ado, here is the code..
simple.h
enum eEngineObjectKind
{
eMeshObject = 0,
eSkeletonObject,
nEngineObjectKinds
};
typedef float t_TRANSFORM[16];
typedef void (*UpdateFunctionPtr)(float time_delta);
extern UpdateFunctionPtr update_jump_table[nEngineObjectKinds];
template <typename T> class EngineObject
{
private:
T* object_data;
enum eEngineObjectKind kind;
public:
void init_object()
{
kind = T::object_kind;
update_jump_table[kind] = T::object_update_fn;
object_data = new T(); // or T::allocate_object
};
void update_object(float time_delta)
{
update_jump_table[kind](time_delta);
}
};
template <> class EngineObject<void>
{
private:
void *object_data;
eEngineObjectKind kind;
public:
void *getData()
{
return object_data;
}
eEngineObjectKind getKind()
{
return kind;
}
void update_object(float time_delta)
{
update_jump_table[kind](time_delta);
}
};
class EngineMeshData
{
public:
static eEngineObjectKind object_kind;
static UpdateFunctionPtr object_update_fn;
static void UpdateMesh(float time_delta);
};
class EngineSkeletonData
{
public:
static eEngineObjectKind object_kind;
static UpdateFunctionPtr object_update_fn;
static void UpdateSkeleton(float time_delta);
};
typedef EngineObject<EngineMeshData> EngineMeshObject;
typedef EngineObject<EngineSkeletonData> EngineSkeletonObject;
simple.cpp
#include <iostream>
#include "simple.h"
/**
* pseudo - vtable !
*/
UpdateFunctionPtr update_jump_table[nEngineObjectKinds];
/**
* skeleton defintions
*/
enum eEngineObjectKind EngineSkeletonData::object_kind = eSkeletonObject;
void EngineSkeletonData::UpdateSkeleton(float time_delta)
{
std::cout << "Update Skeleton\n";
}
UpdateFunctionPtr EngineSkeletonData::object_update_fn = EngineSkeletonData::UpdateSkeleton;
/**
* mesh defintions
*/
enum eEngineObjectKind EngineMeshData::object_kind = eMeshObject;
void EngineMeshData::UpdateMesh(float time_delta)
{
std::cout << "Update Mesh\n";
}
UpdateFunctionPtr EngineMeshData::object_update_fn = EngineMeshData::UpdateMesh;
EngineObject<void> world[2];
int main (int argc, char *argv[])
{
EngineSkeletonObject *skeleton = new(world) EngineSkeletonObject();
skeleton->init_object();
EngineMeshObject *mesh = new(world+1) EngineMeshObject();
mesh->init_object();
world[0].update_object(1.0f);
world[1].update_object(1.0f);
};