std :: shared_ptr深层复制对象

Æle*_*lex 12 deep-copy shared-ptr c++11

在C++ 11上找不到多少,但仅限于提升.

考虑以下课程:

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() ) ) );
    }   
};
Run Code Online (Sandbox Code Playgroud)

假设类Graph有一个复制构造函数:

Graph( const Graph & graph )
Run Code Online (Sandbox Code Playgroud)

我不想有这个 - > _ graph point/share同一个对象!相反,我希望这个 - > _ graph将对象从state._graph深度复制到我自己的- > _ graph复制中.

是否正确的方式是这样的?

std :: make_shared的文档指出:

此外,如果g抛出异常,f(shared_ptr(new int(42)),g())可能导致内存泄漏.如果使用make_shared,则不存在此问题.

还有另一种方法可以解决这个问题,更安全或更可靠吗?

tem*_*def 9

如果要在复制Graph对象时制作对象的副本,可以始终定义复制构造函数和赋值运算符来执行以下操作:

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;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 复制构造函数将`_graph`初始化为`std :: shared_ptr`,它指向一个全新的`Graph`对象,该对象被初始化为原始图的副本.这意味着它最终指向与原始图形分开的新"图形".在移动构造函数中,我们只是将现有的`shared_ptr`移出现有的`State`对象,因为该对象不再被使用. (2认同)
  • 补充说明:`_graph = std :: make_shared <Graph>(*state._graph);`_(注意星号!)_将调用`Graph`的副本ctor,因为`make_shared <T>`接受参数传递给一个ctor,`*state._graph`给出了shared_ptr管理的对象的引用.引用自己类型的ctor将是copy-ctor(假设有一个).如果您只想与另一个shared_ptr共享所有权,那么它只是`_graph(state._graph)`(shared_ptr的copy-ctor).当你想要一个新的`T`对象**(包裹在shared_ptr中)时,你只需要`make_shared`. (2认同)