std::shared_ptr deep copy object
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!
Related videos on Youtube
Æ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, 2022Comments
-
Æ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 over 10 yearsI'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 over 10 yearsThe copy constructor initializes
_graph
to be astd::shared_ptr
that points at a brand-newGraph
object initialized as a copy of the original graph. This means that it ends up pointing to a newGraph
separate from the original graph. In the move constructor, we just move the existingshared_ptr
out of the existingState
object, since that object isn't going to be used any more. -
AnorZaken over 7 yearsAdditional explanation:
_graph = std::make_shared<Graph>( * state._graph );
(note the asterisk!) will call the copy ctor ofGraph
becausemake_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 needmake_shared
when you want a newT
object (wrapped in a shared_ptr).