I am designing and entity-component system for a project, and C++ memory management is giving me a few issues. I just want to make sure my design is legitimate.
So to start I have an Entity class which stores a vector of Components:
class Entity
{
private:
std::vector<std::unique_ptr<Component> > components;
public:
Entity() { };
void AddComponent(Component* component)
{
this -> components.push_back(std::unique_ptr<Component>(component));
}
~Entity();
};
Which if I am not mistaken means that when the destructor is called (even the default, compiler created one), the destructor for the Entity, will call ~components, which will call ~std::unique_ptr for each element in the vector, and lead to the destruction of each Component, which is what I want.
The component class has virtual methods, but the important part is its constructor:
Component::Component(Entity parent)
{
parent.addComponent(this) // I am not sure if this would work like I expect
// Other things here
}
As long as passing this to the method works, this also does what I want. My confusion is in the factory. What I want to do is something along the lines of:
std::shared_ptr<Entity> createEntity()
{
std::shared_ptr<Entity> entityPtr(new Entity());
new Component(*parent);
// Initialize more, and other types of Components
return entityPtr;
}
Now, I believe that this setup will leave the ownership of the Component in the hands of its Parent Entity, which is what I want. First a small question, do I need to pass the entity into the Component constructor by reference or pointer or something? If I understand C++, it would pass by value, which means it gets copied, and the copied entity would die at the end of the constructor.
The second, and main question is that code based on this sample will not compile. The complete error is too large to print here, however I think I know somewhat of what is going on. The compiler's error says I can't delete an incomplete type. My Component class has a purely virtual destructor with an implementation:
inline Component::~Component() { };
at the end of the header. However since the whole point is that Component is actually an interface. I know from here that a complete type is required for unique_ptr destruction. The question is, how do I work around this? For reference I am using gcc 4.4.6.