如何正确复制给定 shared_ptr 的对象
Posted
技术标签:
【中文标题】如何正确复制给定 shared_ptr 的对象【英文标题】:How to properly duplicate an object given its shared_ptr 【发布时间】:2014-05-12 00:21:17 【问题描述】:我正在尝试复制自定义类 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)
,但据我了解,这不是必需的,因为编译器提供了默认的复制构造函数。事件类只包含变量,没有进一步的指针。
【问题讨论】:
好像e
也删了o
?为何如此?您可以使用 print 语句添加析构函数以查看发生了什么。
您可以将日志放入您的事件析构函数中。例如 std::cout。
【参考方案1】:
您尝试的应该可以正常工作,如果*e
的动态类型是Event
,而不是从Event
派生的某个类。 (如果*e
实际上是从Event
派生的对象,那么您将创建一个新的Event
(不是派生类型)作为*e
的基类部分的副本,即您将“切片”*e
)。
由于您使用make_shared<Event>()
创建了e
,因此您知道在这种情况下它确实是Event
,因此std::make_shared<Event>(*e)
应该创建一个拥有*e
副本的新shared_ptr
。
【讨论】:
我遇到了您所描述的问题。如何从另一个 shared_ptr 到 Base 类创建 shared_ptr 到 Base 类的副本,同时保留它实际上是 Derived 类的事实? 到目前为止我最好的解决方案是:'code' std::shared_ptr`
进行内联代码标记,而不是“代码”。见***.com/editing-help#comment-formatting【参考方案2】:
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);
当然,当它们超出范围时,两个对象都会被销毁。
【讨论】:
make_shared() 是否必须使用新对象进行复制?还是尽可能移动对象? @TheQuantumPhysicistfoo()
中的第二行使用复制构造函数创建了一个新对象 - 它不会移动以上是关于如何正确复制给定 shared_ptr 的对象的主要内容,如果未能解决你的问题,请参考以下文章