标准::shared_ptr的唯一副本
Unique copy of std::shared_ptr
我有一个对象(我们称之为X),其他对象可以通过std::shared_ptr
访问它。但是,在这些对象的某个时刻需要创建 X 的唯一、非共享副本,因为它想要修改它。这在某种程度上类似于写入时复制,但由于其他一些细节,并不完全相同。
基本上我希望有这样的语义:
struct Foo
{
std::shared_ptr<Bar> bar;
void go()
{
// bar.use_count() >= 1
bar.make_this_object_unique();
// bar.use_count() == 1
}
}
如果您只想复制对象,并获得指向新对象的共享指针,那么这就是
bar = std::make_shared<Bar>(*bar);
这假定Bar
是目标的实际类型。如果要复制 Bar
的任意子类,则需要一个虚函数来复制对象,例如:
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();
您可能需要测试bar.unique()
以确定是否需要副本。
在一般情况下是不可能的。在两种情况下可能:
-
存储在 bar 中的对象是 Bar 类型,而不是从 Bar 继承的类。然后只需使用复制构造函数(前提是它可用):
bar = std::make_shared<Bar>(*bar);
-
Bar 或其任何基类以创建新分配的副本的虚拟函数的形式提供克隆功能:
bar = std::shared_ptr<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;
}
为您提供T
的写入复制。 如果它实际上不是T
,这将切片t
。
用途是:
struct Foo
{
std::shared_ptr<Bar> bar;
void go()
{
cow_ptr(bar);
}
}
您甚至可以直接使用它,例如 cow_ptr(bar)->blah()
.
cow
代表"写入时复制"。 cow_ptr
代表"哞哞"。
你可以
做类似的事情
bar = shared_ptr<Bar>(new Bar(*bar));
您需要做的是对基础对象执行正确的复制,因为让两个shared_ptr实例管理相同的内存是行不通的。
相关文章:
- 何时在引用或唯一指针上使用移动语义
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 计算排序向量的向量中唯一值的计数
- 如何使用Visual Studio 2017在C++中为参数化对象数组使用唯一指针
- 用callgrind追踪不必要的副本
- 通过组合不同的类型来创建唯一的id
- 使用Unique_ptr确保工厂中的对象唯一
- c++多进程编写一个唯一的文件
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 检查注册表项是否链接到(或副本)另一个注册表项
- 如何更改唯一指针向量的可见性
- 在C++的两个字符串中连接以逗号分隔的唯一值
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- C++尝试深度复制唯一指针时出现内存访问冲突
- 具有引用成员的结构是否具有唯一的对象表示形式
- 使用 RTTI 克隆唯一指针的向量
- 标准::shared_ptr的唯一副本
- 矢量<unique_ptr>的唯一副本