Why is everything a shared_ptr in ROS2?
Many functions in rclcpp
return a std::shared_ptr
, e.g. create_subscription()
, or take a std::shared_ptr
argument, e.g. subscriber callbacks. This surprises me because it's my impression that it's good practice to use shared pointers only when needed, and prefer a unique_ptr or even plain objects.
For instance, the std::shared_ptr
returned by create_subscription()
appears to be the sole owner of the subscriber, so it could be a std::unique_ptr
instead. Besides being a bit more performant and flexible, this would also serve as documentation: I had to write a test case to find out that there is only one owner and that you can therefore shut down a subscription by resetting it to nullptr
, but if it had been a std::unique_ptr
, that would have been obvious. Similarly, everywhere a pointer is used, it theoretically allows for a nullptr
, but if a function returned a plain object or accepted arguments by reference instead, users of the API could rely on the object never being null.
I'm not sure if plain objects would be possible – maybe rclcpp
uses polymorphism and SubscriptionT
is only a base class, while the true type is hard/impossible to name?
So why is everything a shared pointer in ROS2? I hope a broad question like makes sense, but if not, my main questions would be:
- Why are there no versions of
create_subscription()
andcreate_publisher()
that return unique pointers or plain objects? - Why do the subscription callbacks not receive messages by reference?
I'd also be interested in some discussion surrounding this. It's also easy to convert a unique_ptr to a shared_ptr if shared ownership is needed during runtime. My guess is that it's done this way to simplify the overall interface during the initial development of ROS2. This sets a bad precedent for clear ownership however, as you have pointed out.
Any updates on this? My team is trying to make the switch to ROS2 but have the exact same questions ...
For an authoritative answer, we'll need input from someone who was present when this design choice was made.
Perhaps @William, or one of the other "core devs" of ROS 2.
Though not a direct and complete answer to your question, when I was searching for the same question I found the ROS 2 design article Intra-process Communications in ROS 2 that provides interesting information on using different type of smart pointers for publishers and subscribers