C++ std::shared_ptr的唯一副本
我有一个对象(我们称之为X),其他对象可以通过C++ std::shared_ptr的唯一副本,c++,c++11,C++,C++11,我有一个对象(我们称之为X),其他对象可以通过std::shared\u ptr访问它。但是,在某些情况下,这些对象需要创建一个唯一的、非共享的X副本,因为它想要修改它。这在某种程度上类似于写时复制,但由于其他一些细节的原因,并不完全相同 基本上,我希望有这样的语义: struct Foo { std::shared_ptr<Bar> bar; void go() { // bar.use_count() >= 1 bar.make_this_obj
std::shared\u ptr
访问它。但是,在某些情况下,这些对象需要创建一个唯一的、非共享的X副本,因为它想要修改它。这在某种程度上类似于写时复制,但由于其他一些细节的原因,并不完全相同
基本上,我希望有这样的语义:
struct Foo
{
std::shared_ptr<Bar> bar;
void go()
{
// bar.use_count() >= 1
bar.make_this_object_unique();
// bar.use_count() == 1
}
}
structfoo
{
std::共享的ptr条;
void go()
{
//bar.use_count()>=1
bar.make_this_object_unique();
//bar.use_count()==1
}
}
您可以执行以下操作
bar = shared_ptr<Bar>(new Bar(*bar));
bar=shared_ptr(新条(*bar));
您需要做的是在基础对象上执行正确的复制,因为让两个共享的\u ptr实例管理同一个内存是行不通的。如果您只是想复制对象,并获取指向新对象的共享指针,那么这就行了
bar = std::make_shared<Bar>(*bar);
您可能需要测试bar.unique(),以确定是否需要复制。在一般情况下不可能。可能有两种情况:
bar=std::使_共享(*bar)代码>
bar=std::shared_ptr(bar->Clone())代码>
cow\u ptr(bar)->blah()
cow
代表“写时复制”cow_ptr
代表“moo”。你的意思是bar=std::make_shared(*bar)代码>,为从旧对象复制的新对象提供(唯一)共享指针?还是我错过了什么?@MikeSeymour他不能这样做,因为那样会有两个共享的\u ptr实例监视同一个指针。它们中的任何一个都可能删除该资源。您将如何使保存该资源的其他共享指针无效?@sbaker:不,不会make_shared
将创建一个新对象,复制旧对象,并返回指向该对象的共享指针。现有指针仍将管理旧对象。抱歉@MikeSeymour,你是对的。我需要更仔细地阅读——我想我读的是共享的,而不是共享的。谢谢。这与我到目前为止使用的C++11之前的指针类的语义有所不同,但似乎是合理的。最后一件事——如果对象已经是唯一的,我如何避免复制它?
struct Bar {
virtual std::shared_ptr<Bar> clone() = 0;
};
struct SomeKindOfBar : Bar {
virtual std::shared_ptr<Bar> clone() {
return std::make_shared<SomeKindOfBar>(*this);
}
};
bar = bar->clone();
template<typename T>
std::shared_ptr<T>& cow_ptr( std::shared_ptr<T>& t ) {
if (t && !t.unique())
t = std::make_shared<T>( *t );
return t;
}
struct Foo
{
std::shared_ptr<Bar> bar;
void go()
{
cow_ptr(bar);
}
}