Why I recommend the template version is because modern c++ avoids raw pointers (shared_ptr/unique_ptr instead). These cannot be returned by a constructor and yet the memory still gets bound to a smart pointer in a list of components. Try out both solutions and I am sure you will find the template version safer and more elegant.
C++ Angle bracket function
Why I recommend the template version is because modern c++ avoids raw pointers (shared_ptr/unique_ptr instead).
Why do you need to write a template of your own to use smart pointers? Here.
You certainly don't need to but it avoids risk of something wrong like this:
Component(GameObject& go)
{
go.components.push_back(std::shared_ptr<Component>(this));
}
This is wrong because if this constructor is used within make_shared<T> then there will be a double delete.
Also, I prefer the template version because your example seems to take ownership from another unique_ptr (which I don't really like nd is not appropriate in a lot of situations) and if a shared_ptr was to be used instead, there is some redundant ref counting machinery happening behind the scenes. I much prefer something like this:
std::weak_ptr<SomeComponent> sc = gameObject->addComponent<SomeComponent>();
This is good because it actively suggests to the developer that the ownership and lifespan on the component is now handled elsewhere (in the GameObject) rather than by the reference returned.
Also, arguably since the component hasn't actually been added to a game object by the time the constructor runs, it isn't quite fully "constructed" in that it cannot use it's parent GameObject or siblings. Thus I prefer the addComponent function to trigger the Awake() function (just like in Unity) where much of the processing is done. Technically the way Unity does it is a form of Two stage construction which is normally quite naff but works well in this case.
Yes it does come down to personal preference, and yes there are ways I prefer as an alternative to any of this but since my project is a clone of Unity I am a bit restricted in what I can do haha.
Probably because templates are fancy and shiny. Pointers to base classes are old-school and ghetto.
Just curious, how are you avoiding a base class pointer as the container type? Are you having a container for each type of object?
Sorry for not replying for a while! I managed to get it all sorted out thanks to your help!
It would be nice if you could give us a brief description of what worked for you. That way this thread would be more helpful to people that find it in the future when they have a similar problem to yours.