单一所有权与共有所有权的含义
single vs shared ownership meaning
刚刚看到Single
和Shared
的所有权时,正在为RAII阅读维基百科。
在谷歌上搜索,却找不到任何有用的答案!
有人能为一个小学生解释这个概念吗?
本质上是unique_ptr
与shared_ptr
。
单一所有权,也称为唯一所有权,意味着资源由单个类实例所有。一旦该实例不存在,资源就会被释放(通过析构函数)。您发现的大多数RAII类都具有唯一的所有权,例如std::vector
。
共享所有权意味着资源在多个类实例之间共享。只有当每个实例都不存在时,才会释放资源,因此需要某种形式的引用计数或垃圾收集。您想要共享所有权的一个例子是一个非常昂贵的复制不可变资源的句柄。我也看到它在图表中使用过。
从指针的角度思考可能会有所帮助。单一所有权将只有一个拥有指针,共享将有多个。当然,RAII可能不涉及指针。
+---------------+
|Shared instance|
+--------+ +------------+--+ +---------------+
|Resource| | +----------+Shared instance|
+--------+ v v +---------------+
^ +--------+
| |Resource|<-----------+
| +--------+ +---+-----------+
| ^ |Shared instance|
+------+--------+ | +---------------+
|Unique Instance| |
+---------------+ |
+------+--------+
|Shared instance|
+---------------+
所有权与可变寿命的概念密切相关。
如果你能回答这个问题,这段内存什么时候可以消失,那么你就可以回答所有权的问题了。
如果内存块只与一个变量的生存期绑定,那么您就拥有单一所有权。
请注意,考虑堆或动态分配与堆栈和自动变量也很重要。使用自动变量,当它们超出范围时,将获得与其相关的内存。对于动态分配,在一般情况下情况并非如此。如果您使用std::unique_ptr<>之类的新设施对于单一所有权,那么当一块动态内存超出范围时,您可以让它自行清理。如果有许多对该内存块的引用,并且这些引用何时消失的顺序不确定,那么您可能需要类似于std::shared_ptr<>的东西表示多重所有权。
所有权可以归结为谁负责释放资源。通常,您可以说代码的一部分(无论是函数还是类)是资源的唯一所有者。当完成对资源的处理时,所有者将不得不释放它,以使资源不会泄漏。这被称为单一所有权或唯一所有权。
同样,也存在共享所有权的概念,即代码的两个或多个离散部分,也可以是类或函数,都依赖于同一资源。在这种情况下,在释放资源之前,两者都必须不再需要资源。
C++提供了两个有用的包装器来传达和执行所有权语义——所有权语义如上所述。这些包装器概括了RAII的概念——一旦资源超出范围,就会自动释放资源。
-
unique_ptr
——当一个封装在唯一指针中的对象超出范围时,它将立即被释放,这意味着函数返回或类被销毁。 -
shared_ptr
——封装在共享指针中的对象将保持可用,直到所有"强引用"都超出范围。这是一个被称为参考计数的概念。一旦最终引用超出范围,资源就会被释放。
所有权语义在C++等语言中非常重要,因此我建议您熟悉现代C++是如何传达和执行它的。您可以从学习unique_ptr
和shared_ptr
的正确用法开始。
关于智能指针/raii,共享所有权是指多个对象可以引用同一资源,只有当引用该资源的对象的所有实例都被解构时,该资源才会被释放。
// shared ownership
{
std::shared_ptr<SomeClass> i(new SomeClass());
{
std::shared_ptr<SomeClass> j = i;
{
std::shared_ptr<SomeClass> k = j;
// at this point i, j, k all own the same object
}
// k deconstructed and no longer shares ownership of the resource
}
// j deconstructed and no longer shares ownership of the resource
}
// i deconstructed and he resource is also released / free'd
共享(唯一)所有权要么与对象一起消亡,要么传递给另一个对象
// single/unique ownership
{
std::unique_ptr<SomeClass> i(new SomeClass());
{
std::unique_ptr<SomeClass> j = std::move(i); // k takes ownership of the object from i
}
// j is deconstructed and the resource is also released / free'd
}
// i deconstructed and nothing is released, as the ownership already passed to j
单一所有权意味着当所有者完成一个资源时,它应该删除它。
如果它是共享所有权,那么它就不能删除它,因为其他所有者可能仍在使用它!因此,资源删除必须通过某些方式进行协调,通常通过引用计数。
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 智能指针概念所有权和寿命
- CRTP 单一实例不完整类型或非文本类型
- 对象超出范围/转让所有权
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- 在不授予所有权的情况下公开shared_pointers载体
- 分离类所有权和使用,生成最佳(快速)代码
- std::unique_ptr 在获得所有权之前进行测试
- Qt对象所有权内存泄漏
- 避免从单一元素向量转换为基元类型
- C++析构函数和所有权
- 分叉后对全局资源的所有权
- 为什么这不违反单一定义规则?
- 如何将对象的所有权传递给函数的外部
- make_unique 不会为创建单一实例进行编译
- 使shared_ptr失去对内存的所有权
- C++ 中的基本单一实例对象
- 唯一 ptr 将所有权移动到包含对象的方法
- 单一所有权与共有所有权的含义
- 如何使用weak_ptr强制执行单一所有权?(或者,如何子类化shared_ptr并覆盖dtor)