So going through books and code I see smart pointers and naked pointers and am wondering if there are situations where i have to use a naked pointer during game design or if I can and should always use smart pointers?
I was looking through a book and one of the examples was explaining about holding a list of drawable objects in a vector and the vector looked like this:
because if we have Enemy and Ship objects, they can be different sizes, but a pointer is always the same size, so is:
Who owns object? Who is responsible of managing its lifetime? What does the manager need to know?
If you have to refer to object that you don't own and you are sure that you will quit referencing to it before it ceases to exist, then do you need a smart pointer?
What is the size of a std::shared_ptr object? Does it contain more data than just the raw pointer? Are there operations that it has to perform "under the hood"? Are they cheap?
Scott Meyers discusses smart pointers in his Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14
Well to be honest I dont know a whole lot about pointers, I know how they work but I literally never use pointers in the over 10 years i've been using C++, I just use references.
But when it comes to game design, it's probably going to be unavoidable. I tend to keep away from pointers unless I have no other choice. I will need to load images like sprite sheets and tiles into vectors and i'll be using SFML, which has a Texture class, which I learned is not a cheap thing, it's pretty expensive so vectors will be loading images and holding class objects of enemies and other actors that have data such as sprite data, movement and rotation data, collision etc, so i'm unsure how large or small they would be.
> wondering if there are situations where i have to use a naked pointer during game design
> or if I can and should always use smart pointers?
>> Who owns object? Who is responsible of managing its lifetime?
The design decision should depend on the answer to that question.
Using a smart pointer is wrong if the component (function, container etc.) just needs an object and is not involved in managing the life-time of the object. If we need a vector of pointers to Drawable objects, and the vector itself does not have a say in managing the lifetime of these Drawable objects, it should just be a std::vector<Drawable*> or alternatively, if an object must always be present (it would never be a nullptr), then std::vector< std::reference_wrapper<Drawable> >. Except to the crowd that unthinkingly repeats by rote 'never use raw pointers', it is easy to see that the 'no smart pointers are required here' decision yields a more flexible design: the vector itself has no business insisting that these Drawable objects must only be created in a particular way; it should be able to accept any Drawable object.
Conversely, if the vector is actually involved in managing the life-time of the object, use a smart pointer. In general, favour unique pointers over shared pointers; designs with unique ownership are cleaner and conceptually simpler; the performance implication of this decision is only a secondary consideration.