C++ Value/Reference/(Smart) Pointer Guide
Unfortunately this table is not very mobile friendly. Assuming C
is a sufficient large class:
C |
const C |
C & |
const C & |
C * const C * |
unique_ptr<C> shared_ptr<C> [1] |
|
---|---|---|---|---|---|---|
Parameter | Sink parameter or if a copy is always needed. | (Don't) | Out or In-Out parameter | In parameter (Default) | Special treatment like, "This function stores the pointer for later use." Look at the function's documentation. (Avoid) | Pass ownership to the function. |
Return Value | (Default) | (Don't) | If you want to provide function chaining, you can return *this
or a C & /const C & parameter. (Dangerous) |
Special treatment like, "You have to free this pointer yourself." Look at the function's documentation. (Avoid) | Pass ownership to the caller. | |
Catch Exceptions | (Don't) | (Don't) | (Avoid) | (Default) | (Don't)[2] | (Don't) |
Member Variables | (Default) | For implementing a truly immutable type. This most likely disables assignment and move semantics! (Avoid) | (Don't) | (Don't) | Object identity is relevant or polymorphism is required. Use smart pointers instead, except if lifetime is no issue. (Avoid) | Object identity is relevant or polymorphism is required. Has lifetime semantics. |
Local[3] Variables | If the value has to be mutable. | (Default) | If an alias to a value is required. | If you need an alias with null sematics. Consider std::optional instead. |
If required. |
Whats about C &&
? Only use it for implementing move constructors or move assignment operators or if you are implementing a template function that requires perfect forwarding. const C &&
does not make sense in any case.
Footnotes:
- Including their const/non-standard variants. Jump back.
- Required for MFC. Jump back.
- Mostly applies to static variables as well. Jump back.