Say in a game engine, you have Object
s that composited of different components. One of these is a RenderComponent
which can be either a Mesh
, a Sprite
or a Light
.
Now, all these are vastly different classes with non-complatible interfaces, so deriving them all from RenderComponent
makes little sense. Also, an Object
can only have one RenderComponent
at a time, so you saving three pointers in Object
, two of which must always be nullptr
, seems wasteful. So what I came up with is using RenderComponent
to store a void*
pointer and the type.
class RenderComponent{
public:
enum class RenderType{
Mesh, Sprite, Light
};
RenderType getType(){ return type_; }
Mesh* asMesh(){
if(type_ == RenderType::Mesh)
return static_cast<Mesh*>(pointer_.get())
else
return nullptr;
} /* the same stuff for Sprite and Light */
RenderComponent(unique_ptr<Mesh>&& pointer) :
pointer_(std::move(pointer)),
type_(RenderType::Mesh)
{} /* the same stuff for Sprite and Light */
private:
unique_ptr<void> pointer_;
RenderType type_;
}
It should work as intended, but I feel like this is an anti-pattern. I'm basically discarding all typesafe aspects of C++ and then reimplement them myself. This can't be right.
So, is this an anti-pattern? What are common workarounds for this problem? Am I missing something obvious? Or is this a known, but (for good reason) only rarely used pattern?