I am currently working on some code that needs to allow semi-arbitrary c++ classes to be instantiated at runtime, meaning if e.g. a user inputs "Class1", a new instance of Class1
will be instantiated.
All of this is necessarily stored in void* form because the classes do not necessarily share any base classes (and I'd like to support primitives as well, but I'm not currently doing so)
The void* are cast to the correct type upon use, but the issue arises in that I'm also allowing them to be used as a pointer to a base class.
e.g.
void* p = new Derived();
((Base*)p)->someVirtualFunction();
I need a way to cast to the base correctly. obviously if I had the type easily accessible, I could just:
void* p = (Base*)(new Derived());
((Base*)p)->someVirtualFunction();
and there wouldn't be an issue.
However I don't have the type that easily accessible.
I do have an infrastructure in place:
class Type {};
template<typename T>
class TypeImpl : public Type {};
in the actual code, these have many functions which are not relevant to the problem at hand.
I have access to a Type*
which points to a TypeImpl<Base>
and one which points to a TypeImpl<Derived>
I'm attempting to find a way to use these to cast the pointer correctly e.g.
class Type {
void* cast(Type* type_of_p, void* p)=0;
template<typename C>
void* castTo(void* p)=0;
};
template<typename T>
class TypeImpl : public Type {
void* cast(Type* type_of_p, void* p){
return type_of_p->castTo<T>(p);
}
template<typename C>
void* castTo(void* p){
return ((C*) ((T*) p));
}
};
but without virtual function templates, I can't find a way to do this.
As for other solutions, my closest thought is maybe some kind of hashmap of hashmaps of function pointers that indexes on std::type_index
but I haven't been able to get that to work either.
Is this possible, and if so, how might I go about it?
EDIT TO HOPEFULLY CLARIFY:
I have a void* p
that points to a Derived
I need to cast it to a Base*
(e.g. void* p = new Derived();
)
(Base*)p
or any type of cast that does not use runtime information is not valid as the vtable is misaligned.
I need something like:
(Base*)(Derived*)p
(or equivalent c++ casts) but I don't know which derived class it is.
I'm not sure if I'm just wording this very poorly or if there's some mistake I'm making but that's the core issue.