std::shared_ptr deep copy object

16,230

If you want to make a copy of the Graph object when you make a copy of the object, you can always define your copy constructor and assignment operator to do just that:

State::State(const State& rhs) : _graph(std::make_shared(*rhs._graph)) {
   // Handled by initializer list
}
State::State(State&& rhs) : _graph(std::move(rhs._graph)) {
   // Handled by initializer list
}
State& State::operator= (State rhs) {
    std::swap(*this, rhs);
    return *this;
}

Hope this helps!

Share:
16,230

Related videos on Youtube

Ælex
Author by

Ælex

I'm an ML/AI researcher who sold his soul to the industry. I love working on RL, ML, CV using Python (PyTorch, Keras, TF, etc). Used to work on C++/ROS/OpenCV for Robotics. I'm not looking for a job, but I'm definitely interested in Startups.

Updated on September 16, 2022

Comments

  • Ælex
    Ælex over 1 year

    Can't find much on that for C++11 but only on boost.

    Consider the following class:

    class State
    {
       std::shared_ptr<Graph> _graph;
    
     public:
    
        State( const State & state )
        {
            // This is assignment, and thus points to same object
            this->_graph = std::make_shared<Graph>( state._graph ); 
    
            // Deep copy state._graph to this->_graph ?
            this->_graph = std::shared_ptr<Graph>( new Graph( *( state._graph.get() ) ) );
    
            // Or use make_shared?
            this->_graph = std::make_shared<Graph>( Graph( *( state._graph.get() ) ) );
        }   
    };
    

    Suppose class Graph does have a copy constructor:

    Graph( const Graph & graph )
    

    I do not want to have this->_graph point/share the same object! Instead, I want this->_graph to deep copy the object from state._graph, into my own this->_graph duplicate.

    Is the way above the correct way of going about this?

    Documentation of std::make_shared notes that:

    Moreover, f(shared_ptr(new int(42)), g()) can lead to memory leak if g throws an exception. This problem doesn't exist if make_shared is used.

    Is there another way of going about this, safer or more reliable?

  • Ælex
    Ælex over 10 years
    I'm even more curious now. The first Copy constructor you have, simply assigns the same graph, does it not? Whereas the second one uses move, which would move, not duplicate the object, no?
  • templatetypedef
    templatetypedef over 10 years
    The copy constructor initializes _graph to be a std::shared_ptr that points at a brand-new Graph object initialized as a copy of the original graph. This means that it ends up pointing to a new Graph separate from the original graph. In the move constructor, we just move the existing shared_ptr out of the existing State object, since that object isn't going to be used any more.
  • AnorZaken
    AnorZaken over 7 years
    Additional explanation: _graph = std::make_shared<Graph>( * state._graph ); (note the asterisk!) will call the copy ctor of Graph because make_shared<T> takes arguments to pass to a ctor, and *state._graph gives a reference to the object managed by the shared_ptr. A ctor that takes a reference of its own type would be the copy-ctor (assuming there is one). If all you wanted was to share ownership with another shared_ptr then it would simply be _graph(state._graph) (copy-ctor of shared_ptr). You only need make_shared when you want a new T object (wrapped in a shared_ptr).