在线文档教程
C++
应用 | Utilities

std::shared_ptr::shared_ptr

STD::共享[医]PTR::共享[医]PTR

constexpr shared_ptr((1)
constexpr shared_ptr( std::nullptr_t (2)
template< class Y > explicit shared_ptr( Y* ptr (3)
template< class Y, class Deleter > shared_ptr( Y* ptr, Deleter d (4)
template< class Deleter > shared_ptr( std::nullptr_t ptr, Deleter d (5)
template< class Y, class Deleter, class Alloc > shared_ptr( Y* ptr, Deleter d, Alloc alloc (6)
template< class Deleter, class Alloc > shared_ptr( std::nullptr_t ptr, Deleter d, Alloc alloc (7)
template< class Y > shared_ptr( const shared_ptr<Y>& r, element_type *ptr (8)
shared_ptr( const shared_ptr& r (9)
template< class Y > shared_ptr( const shared_ptr<Y>& r (9)
shared_ptr( shared_ptr&& r (10)
template< class Y > shared_ptr( shared_ptr<Y>&& r (10)
template< class Y > explicit shared_ptr( const std::weak_ptr<Y>& r (11)
template< class Y > shared_ptr( std::auto_ptr<Y>&& r (12)(until C++17)
template< class Y, class Deleter > shared_ptr( std::unique_ptr<Y,Deleter>&& r (13)

构造新shared_ptr引用要管理的对象的各种指针类型。

For the purposes of the description below, a pointer type Y* is said to be compatible with a pointer type T* if either Y* is convertible to T* or Y is the array type UN and T is U cv .(since C++17)

1-2%29构造shared_ptr没有托管对象,即为空shared_ptr

3-7%29构造ashared_ptr带着ptr作为指向托管对象的指针。

Y* must be convertible to T*.(until C++17)
If T is an array type UN, these constructors do not participate in overload resolution if Y(*)N is not convertible to T*. If T is an array type U[], these constructors do not participate in overload resolution if Y(*)[] is not convertible to T*. Otherwise, these constructors do not participate in overload resolution if Y* is not convertible to T*.(since C++17)

此外:

3%29使用删除-表达式delete ptr如果T不是数组类型;delete[] ptr如果T是数组类型%28,因为C++17%29作为删除项。Y必须是一个完整的类型。DELETE表达式必须格式良好,具有定义良好的行为,并且不引发任何异常.。如果DELETE表达式格式不正确,则此构造函数不参与重载解析。%28自C++17%29

4-5%29使用指定的删除器。d作为删除者。表达d(ptr)必须有良好的格式,有明确的行为,不抛出任何异常.。建筑d和存储的删除器的d不能抛出异常。

Deleter must be CopyConstructible.(until C++17)
These constructors additionally do not participate in overload resolution if the expression d(ptr) is not well-formed, or if std::is_move_constructible<D>::value is false.(since C++17)

6-7%29与%284-5%29相同,但另外使用alloc用于内部使用的数据分配。Alloc一定是Allocator...

8%29混叠构造函数*构造shared_ptr共享所有权信息的r,但是持有一个不相关的非托管指针。ptr即使这个shared_ptr是组中最后一个超出作用域的对象,它将为最初由r.然而,打电话get()上,将始终返回ptr程序员有责任确保ptr只要这个共享[医]PTR存在,例如在典型用例中ptr管理的对象的成员。r或者别名%28e。g.,下降%29%r.get()

9%29构造一个shared_ptr共享由r.如果r不管理对象,*this也不管理对象。如果以下情况下,模板重载不参与重载解决方案Y*在C++17%29之前不能隐式转换为%28兼容%28自C++17%29T*...

10%29移动-构造一个shared_ptrr.施工后,*this包含上一状态的副本。r,,,r为空,其存储的指针为空。如果以下情况下,模板重载不参与重载解决方案Y*在C++17%29之前不能隐式转换为%28兼容%28自C++17%29T*...

11%29构造一个shared_ptr共享由r...Y*必须隐式转换为T*.%28直到C++17%29,此重载只参与以下情况下的过载解决方案:Y*与T*.%28自C++17%29以来r.lock()可以用于相同目的:区别在于,如果参数为空,则此构造函数将引发异常,而std::weak_ptr<T>::lock()构造空std::shared_ptr那样的话。

12%29构造一个shared_ptr存储和拥有以前由r...Y*必须可转换为T*.建造后,r是空的。

13%29构造一个shared_ptr管理当前由r.与r存储,以供以后删除托管对象。r调用后不管理对象。

This overload doesn't participate in overload resolution if std::unique_ptr::pointer is not compatible with T*. If r.get() is a null pointer, this overload is equivalent to the default constructor (1).(since C++17)

如果Deleter是引用类型,等效于shared_ptr(r.release(),std::ref(r.get_deleter()).否则,相当于shared_ptr(r.release(), r.get_deleter())

注记

重载%283%29、%284%29和%286%29启用共享[医]从[医]这和ptr,并且重载%2813%29启用共享[医]从[医]返回指针的r.release()...

构造者使shared_from_this用指针ptr类型U*意味着它决定U具有明确和可访问的基类,该基类是std::enable_shared_from_this,如果是这样,构造函数将计算语句:

二次

if (ptr != nullptr && ptr->weak_this.expired()) ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>(*this, const_cast<std::remove_cv_t<U>*>(ptr)

二次

何地weak_this是隐藏的可变的std::weak_ptr成员std::shared_from_this.给弱者的任务[医]该成员不是原子成员,并且与对同一对象的任何可能并发访问相冲突。这确保了将来调用shared_from_this()将与shared_ptr由此原始指针构造函数创建。

试验ptr->weak_this.expired()在上面的解说代码中,确保弱[医]如果它已经指示了所有者,则不会重新分配。从C++17开始,就需要进行此测试。

原始指针重载假定对指向对象拥有所有权。因此,构建一个shared_ptr对象已经管理的对象使用原始指针重载。shared_ptr,如通过shared_ptr(ptr.get())可能导致未定义的行为,即使对象的类型为std::enable_shared_from_this...

因为默认构造函数是constexpr,静态共享[医]PTRS被初始化为静态非局部初始化,在任何动态的非本地初始化开始之前。这样就可以安全地使用共享[医]任何静态对象的构造函数中的PTR。

在C++11和C++14中,构造一个std::shared_ptr<T>从std::unique_ptr<T[]>*

二次

std::unique_ptr<int[]> arr(new int[1] std::shared_ptr<int> ptr(std::move(arr)

二次

因为shared_ptr获得其缺失%28astd::default_delete<T[]>对象%29来自unique_ptr,数组将被正确地解除分配。

在C++17中不再允许这样做。相反,数组表单std::shared_ptr<T[]>应该用。

参数

ptr-a pointer to an object to manage
d-a deleter to use to destroy the object
alloc-an allocator to use for allocations of data for internal use
r-another smart pointer to share the ownership to or acquire the ownership from

例外

1-2%29

noexcept规格:

noexcept

3%29std::bad_alloc如果需要,无法获得额外的内存。可能会为其他错误抛出实现定义的异常。delete ptr如果T不是数组类型,delete[] ptr否则,如果发生异常,将调用%29%28,因为C++17%29将被调用。

4-7%29std::bad_alloc如果需要,无法获得额外的内存。可能会为其他错误抛出实现定义的异常。d(ptr)如果发生异常,则调用。

8-10%29

noexcept规格:

noexcept

11%29std::bad_weak_ptr如果r.expired() == true构造函数在这种情况下不起作用。

12%29std::bad_alloc如果需要,无法获得额外的内存。可能会为其他错误抛出实现定义的异常。如果发生异常,此构造函数无效。

13%29如果引发异常,则构造函数没有任何效果。

二次

#include <memory> #include <iostream> struct Foo { Foo() { std::cout << "Foo...\n"; } ~Foo() { std::cout << "~Foo...\n"; } }; struct D { void operator()(Foo* p) const { std::cout << "Call delete from function object...\n"; delete p; } }; int main() { { std::cout << "constructor with no managed object\n"; std::shared_ptr<Foo> sh1; } { std::cout << "constructor with object\n"; std::shared_ptr<Foo> sh2(new Foo std::shared_ptr<Foo> sh3(sh2 std::cout << sh2.use_count() << '\n'; std::cout << sh3.use_count() << '\n'; } { std::cout << "constructor with object and deleter\n"; std::shared_ptr<Foo> sh4(new Foo, D() std::shared_ptr<Foo> sh5(new Foo, [](auto p) { std::cout << "Call delete from lambda...\n"; delete p; } } }

二次

产出:

二次

constructor with no managed object constructor with object Foo... 2 2 ~Foo... constructor with object and deleter Foo... Foo... Call delete from lambda... ~Foo... Call delete from function object... ~Foo..

二次

另见

make_sharedcreates a shared pointer that manages a new object (function template)
allocate_sharedcreates a shared pointer that manages a new object allocated using an allocator (function template)

© cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

http://en.cppreference.com/w/cpp/Memory/Shared[医]PTR/共享[医]PTR