Smart pointer general guidelines

Modern pointer guidelines for C++ are confusing, so I wanted to gather a list of general guidelines for pointer use. I’m sure I’m missing some though that could be added.

Most of these were taken from gotw-91.

  1. Don’t pass a smart pointer as a function parameter unless you want to use or manipulate the smart pointer itself, such as to share or transfer ownership. Only pass a smart pointer if you intend to share ownership.
  2. Prefer passing objects by value, *, or &, not by smart pointer.
  3. Pass by * or & to accept a widget independently of how the caller is managing its lifetime.
  4. Use a * if you need to express null (no widget), otherwise prefer to use a &; and if the object is input-only, write const widget* or const widget&.
  5. Put pointer in class header almost all of the time. Prefer using the pimpl idiom.
  6. You can put a reference in a class header, but it must be set at construction time, passed into the constructor. (dependency injection)
  7. Prefer unique_ptr to shared_ptr
  8. Express a “sink” function using a by-value unique_ptr parameter:
  9. Use a non-const unique_ptr& parameter only to modify the unique_ptr.
  10. Don’t use a const unique_ptr& as a parameter; use widget* instead.
  11. If it can be null, pass widget*, if it can’t be null, use &.
  12. Express that a function will store and share ownership of a heap object using a by-value shared_ptr parameter.
    1. Don’t normally use this because it restricts the lifetime of the caller.
    2. This is used to modify the shared_ptr itself.
    3. void f( shared_ptr& );
  13. Use a non-const shared_ptr& parameter only to modify the shared_ptr.
  14. Use a const shared_ptr& as a parameter only if you’re not sure whether or not you’ll take a copy and share ownership; otherwise use widget* instead (or if not nullable, a widget&).

References:
https://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters

Comments are closed.