Ownership and raw pointers?
Smart pointers usually comes with ownership semantics, so using any of them when you don't want to give/share ownership is a bad idea.
In my own code, I decided the following convention:
raw pointers means no ownership transfer/sharing
This means that if some functions receives a raw pointer as a parameter, then it does not have ownership (and thus, should not try to delete it). In the same way, a function returning a raw pointer does not transfer/share ownership (thus, again, the caller should not try to delete it).
So in your case, you can return a pointer instead of a smart pointer.
Pointer or Reference?
This means the choice between pointer and reference depends only on one factor resolved by the following rule:
- If a
nullptr
/NULL
value makes sense, then use pointers.
- If a
nullptr
/NULL
value makes no sense and/or is undesirable, then use references.
constness and member variables?
I saw some answers on constness, so I add my own two-cents:
Returning a non-const value to an internal variable is a design choice. What you must do is to choose between the following getters:
const Transform * getTransform() const ;
Transform * getTransform() ;
I call (abusively) the accessors above a "property", and the non-const version enables the user to modify the internal Transform object at his/her leisure, without needing to ask your class first. You'll note that if the GameObject is const, there is not way to modify its internal Transform object (the only accessible getter is the const one, returning const). You'll note, too, that you can't change the address of the Transform object inside GameObject. You can only change the data pointer by that address (which is different from making the member variable public)
const Transform *& getTransform() const ;
Transform *& getTransform() ;
This is like the situation above, but thanks to the reference, the user have direct access to the pointer address, meaning the non-const accessor is, more or less, akin to make the member variable public.
const Transform * getTransform() const ;
void setTransform(Transform * p_transform) ;
I call (abusively) the accessors above a "getter/setter": If the user wants to modify the transform value, then he must use the setTransform. You have a lot more control on what you're doing (note that in my code, the setter you pass a unique_ptr or a auto_ptr to express the acquisition of total ownership on the p_transform object. You'll note that if the GameObject is const, there is not way to modify its internal Transform object (the setter is non-const).
Transform * getTransform() const ;
I call (abusively) the accessor above a "subscript", as in arrays of pointers, the array can be const, and thus the internal address is const, but the data pointed by this address is non-const, so it can be modified. This usually means that the Transform object is not really "owned" by your GameObject object. Indeed, it is probable GameObject only references some external object, for ease of use.