如何在给定shared_ptr的情况下正确复制对象

时间:2014-04-01 09:50:45

标签: c++ shared-ptr copy-constructor

我正在尝试复制自定义类Event的对象。我有一个指向我从其分配中获得的对象的共享指针:

std::shared_ptr<Event> e = std::make_shared<Event>();

为了获得e的真实副本(不仅仅是指针的副本),我试过了:

std::shared_ptr<Event> o = std::make_shared<Event>(*e);

但我不确定这是否正确,因为如果我删除e它也会删除o ...

顺便说一句,我还没有定义复制构造函数Event::Event(const Event &orig),但在我的理解中,这不是必需的,因为编译器提供了一个默认的复制构造函数。事件类只包含变量而没有其他指针。

2 个答案:

答案 0 :(得分:9)

std::make_shared只是一个简单的模板函数,可以创建对象,将所有参数传递给构造函数:

template<class T, class... Args>
shared_ptr<T> make_shared(Args&&... args)
{
  return shared_ptr<T>( new T( std::forward<Args>( args )... ) );
}

在您的特定情况下:

std::shared_ptr<Event> o = std::make_shared<Event>(*e);

复制对象。

如果你的代码是这样的话:

void foo() {
    // create new object using default constructor
    std::shared_ptr<Event> e = std::make_shared<Event>();
    // create new object using copy constructor constructor
    std::shared_ptr<Event> o = std::make_shared<Event>(*e);
}

当然,当它们超出范围时,两个对象都会被销毁。

答案 1 :(得分:4)

您尝试的内容应该正常工作,如果 *e的动态类型是Event,而不是某些来自Event的类。 (如果*e实际上是从Event派生的对象,那么您将创建一个新的Event(不是派生类型)作为*e的基类部分的副本,即你会&#34;切片&#34; *e)。

由于您使用e创建make_shared<Event>(),因此您知道在这种情况下它确实是Event,因此std::make_shared<Event>(*e)应该创建一个拥有shared_ptr的新*e {{1}}。

的副本