Use of shared pointers in public interfaces

We have a pretty standard tree API using shared pointers that looks roughly like this (implementations omitted for brevity):

class node;
using node_ptr = std::shared_ptr<node>;

class node : public std::enable_shared_from_this<node> {
    std::weak_ptr<node> parent;
    std::vector<node_ptr> children;

    virtual ~node() = default;

    virtual void do_something() = 0;

    void add_child(node_ptr new_child);

    void remove_child(node_ptr child);

    node_ptr get_parent();

    const std::vector<node_ptr>& get_children();

class derived_node : public node {
    derived_node() = default;

    virtual void do_something() override;

    static node_ptr create(/* args... */);

// More derived node types...

This works just fine and prevents nodes being leaked as you’d imagine. However, I’ve read on various other answers on SO that using std::shared_ptr in a public API like this is considered bad style and should be avoided.

Obviously this ventures into opinion-based territory, so a couple of concrete questions to avoid this question being closed 🙂

  • Are there any well-known pitfalls to using shared_ptrs in interfaces like this, which we have so far been fortunate enough to avoid?

  • If so, is there a commonly-used (I hesitate to say “idiomatic”) alternative formulation which avoids said pitfalls but still allows for simple memory management for users?


Source: c++

Leave a Reply