There are no TestComponent
objects in your vector. They are all Component
s.
void addComponent(Component& comp)
{
std::shared_ptr<Component> test = std::make_shared<Component>(comp);
components.push_back(test);
}
In this function, you create a new Component
object that s a copy of the Component
sub-object of the TestComponent
object you passed in. This is known as object slicing.
You will need to either avoid copying the objects or implement some sort of cloneable interface.
To avoid copying the object, you can do something like this:
class GameObject
{
public:
void addComponent(std::shared_ptr<Component> comp)
{
components.push_back(comp);
}
// ...
};
int main() {
GameObject go;
std::shared_ptr<TestComponent> testComponent = std::make_shared<TestComponent>();
go.addComponent(testComponent);
}
In this case, main
and go
share ownership of a single TestComponent
object. If you want to avoid that, you could implement a clonable interface so that objects know how to copy themselves:
class Component
{
public:
virtual void update(){};
virtual std::shared_ptr<Component> clone() const
{
return std::make_shared<Component>(*this);
}
};
class TestComponent : public Component
{
void update() override;
std::shared_ptr<Component> clone() const override
{
return std::make_shared<TestComponent>(*this);
}
};
class GameObject
{
public:
void addComponent(const Component& comp)
{
components.push_back(comp.clone());
}
// ...
};
int main()
{
GameObject go;
TestComponent comp;
go.addComponent(comp);
}
In this case, you still make a copy, but every class has to override the clone
method.
As for the question about shared_ptr
: std::shared_ptr
is a smart pointer that shares ownership of an object between multiple owners. An object owned by one or more std::shared_ptr
s is only destroyed when all of the std::shared_ptr
objects sharing ownership of it are destroyed. If you don't need this behavior, then std::unique_ptr
exists and will be somewhat more performant. std::unique_ptr
models unique ownership. Only one std::unique_ptr
object can ever reference an object at a time, and the object is destroyed when that std::unique_ptr
is destroyed.
Either type of smart pointer could be used in this situation:
- Use
std::shared_ptr
if you want a GameObject
to be able to share ownership of its components with other owners (perhaps other GameObjects
).
- Use
std::unique_ptr
if you want a GameObject
to have exclusive ownership of its components. In this case the GameObject
could still allow other objects to access its components, but the components' lifetimes would be tied to the lifetime of the GameObject