刚刚看到和拥有时正在阅读RAII的 Wikipedia。Single
Shared
谷歌搜索,找不到任何有用的答案!
有人可以为一个男生解释这个概念吗?
它本质上是unique_ptr
vs shared_ptr
。
单一所有权,也称为唯一所有权,意味着资源由单个类实例拥有。一旦该实例不再存在,资源就会被释放(通过析构函数)。您发现的大多数 RAII 类都有唯一的所有权,例如std::vector
.
共享所有权意味着资源在多个类实例之间共享。只有在每个实例不再存在时才会释放资源,因此需要某种形式的引用计数或垃圾收集。您希望共享所有权的一个例子是一个非常昂贵的复制不可变资源的句柄。我也看到它在图表中使用过。
从指针的角度思考可能会有所帮助。单一所有权将只有 1 个拥有指针,共享将有多个。当然,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
单一所有权意味着当所有者完成资源后,它应该删除它。
如果它是共享所有权,那么它不能删除它,因为其他所有者可能仍在使用它!因此,资源删除必须通过某种方式进行协调,通常是通过引用计数。