Search code examples
c++shared-ptrapi-design

C++ API design shared_ptr and calling into functions


I have similar C++ code to this:

struct Data { /* ... */ }
int SomeFunction1(const Data& data) { return 0; }
int SomeFunction2(std::shared_ptr<Data>& data) { return 0; } // this is non-const though
int SomeFunction3(const Data* data) { return 0; } // possibility of receiving nullptr

int main()
{
  auto data = std::make_shared<Data>(); /* initialization somehow */;
  return SomeFunction1(*data.get()); // (1) call get and dereference the pointer
  return SomeFunction2(data); // (2) create an API that accepts the shared pointer
  return SomeFunction3(data.get()) // (3) create an API that accepts raw pointers
}

Please, ignore for the sake of simplicity that I can use a unique_ptr in this specific example.

To me, (1) seems preferable, but I am wondering whether the code at the caller *data.get() is common or rather some kind of design smell?


Solution

  • Yes, shared.get() is not usually an indicator that everything is going well. However, in your example, you don't need get() because std::shared_ptr overloads operator*, so you can simply say SomeFunction1(*data).

    This is preferably if the function does not take shared ownership of the object, which seems to be the case. Otherwise you would have to copy the std::shared_ptr object.