Question

Usually I use std::unique_ptr to convey ownership and pass in raw pointers as parameters when no ownership is implied. However, I almost never consider a nullptr to be acceptable as an argument, so it would be nice to use references to avoid this, but I'm not sure most people would expect that the object the parameter references needs to exist for the lifetime of the struct A without looking at the source code.

struct A {
    A(B& b)
    :  bPtr(&b) {;}

    void method() {
        // use bPtr
    }

    B* bPtr;
};

The questions are:

1) Is the only option here to stick with pointers and always check for nullptr?

3) Does the fact that A needs bPtr to be valid mean it should take a shared_ptr? If so I feel like I would use shared pointers practically everywhere.

2) Are there conventions that can help convey lifetime requirements for parameters to users besides comments and documentation?

Was it helpful?

Solution

From a C++ language standpoint, your code is fine.

As a C++ user, it depends very much on the semantics of struct A if I would expect it to maintain a reference/pointer to B, make a copy of it or to use the constructor parameter only in the constructor.

My general expectations are (all unless indicated otherwise):

  • If a parameter is passed by (smart) pointer, then the class will likely keep a reference to it
  • If a parameter is passed by (smart) pointer and there is no setter for it, then the class will likely not deal well with null pointers. This can be reinforced by a comment.
  • If a parameter is passed by const reference, then it is safe to pass a temporary object. The receiving object will either make a copy or not use the parameter beyond the constructor.
Licensed under: CC-BY-SA with attribution
scroll top