我对在boost库中实现的智能指针有一些疑问。
shared_ptr和scoped_ptr之间唯一的区别是scoped_ptr没有复制构造函数,shared_ptr有复制构造函数吗?
当对象不调用复制构造函数时,是否应该总是使用scoped_ptr而不是shared_ptr?
我也不了解共享/作用域数组的概念。我不能只使用std::vector代替它吗?
最佳答案
差异比这更根本。它与智能指针如何拥有指向它的对象有关。使智能指针不同于哑指针的原因是所有权的概念是其功能的核心组成部分。所有权语义是区分不同类型的智能指针的原因。
因为智能指针“拥有”它们指向的对象,所以它们可以做一些有用的事情,例如在智能指针消失时删除对象(仅使用语言规则即可;无需编译器魔术)。这样,内存管理几乎可以在C++中实现自动化(尽管相反,现代C++中几乎不需要手动内存管理)。
shared_ptr
实现reference-countingsemantics用于内存管理。多个
shared_ptr
可以拥有一个对象。一种shared_ptr
消失并不一定会删除它的对象指向,因为可能还有另一个
shared_ptr
拥有目的。拥有对象并消失的最后一个
shared_ptr
将删除它拥有的对象。
scoped_ptr
实现排他所有权语义。只有一个scoped_ptr
可以拥有任何一个对象。当scoped_ptr
消失时,它将始终删除其拥有的对象(因为只有一个
所有者)。通常用作轻量级的RAII机制,用于
在免费存储区上分配的对象。
数组版本(
shared_array
和scoped_array
)具有基本相同的语义,但专门为数组设计,例如他们使用delete[]
而不是delete
,实现数组下标运算符,等等。如果默认
shared_ptr
行为不适用于该对象,则shared_array
和delete
也允许您指定自定义删除程序。 scoped_ptr
和scoped_array
不具备此功能,因为与shared_ptr
和shared_array
相比,它们非常轻巧。在C++ 11(最新的C++版本)中,还有一个
unique_ptr
,它与scoped_ptr
一样,只是您可以将对象的所有权转移到另一个unique_ptr
。在C++ 03(一个较老但得到更广泛支持的C++版本)中,存在auto_ptr
与unique_ptr
等效,不同之处在于它很容易以不安全的方式意外地使用它(这就是为什么在C++ 11中不推荐使用)。您选择哪一个都不取决于复制构造函数的存在,因为
shared_ptr
和scoped_ptr
不需要对象是可复制构造的。您可以根据所需的所有权语义选择一个。如果对象具有多个所有者,则可以使用shared_ptr
。如果对象只有一个所有者,并且对象的存在仅在一个范围内持续,请使用scoped_ptr
(因此名为scoped_ptr
)。std::vector
不像shared_array
那样实现引用计数语义。 std::vector
更像scoped_array
,但是可以复制。复制std::vector
时,还复制了它包含的所有元素。 scoped_array
并非如此。 std::vector
还具有允许您操纵和检查其内容的功能(例如push_back
,insert
,erase
等),但比scoped_array
重量更重。