定义于头文件
template< class T > class shared_ptr; (C++11 起)
r 的存储指针用转型表达式获得。- std::static_pointer_cast,
- std::dynamic_pointer_cast,
- std::const_pointer_cast,
- std::reinterpret_pointer_cast
| template< class T, class U > | (1) | (C++11 起) |
| template< class T, class U > | (2) | (C++20 起) |
| template< class T, class U > | (3) | (C++11 起) |
| template< class T, class U > | (4) | (C++20 起) |
| template< class T, class U > | (5) | (C++11 起) |
| template< class T, class U > | (6) | (C++20 起) |
| template< class T, class U > | (7) | (C++17 起) |
| template< class T, class U > | (8) | (C++20 起) |
创建 std::shared_ptr 的新实例,其存储指针从 r 的存储指针用转型表达式获得。
若 r 为空,则新的 shared_ptr 亦然(但其存储指针不必为空)。否则,新的 shared_ptr 将与 r 的初始值共享所有权,除了若 dynamic_pointer_cast 所进行的 dynamic_cast 返回空指针,则为它空。
令 Y 为 typename std::shared_ptr
1-2) static_cast
3-4) dynamic_castdynamic_cast 的结果是空指针值,则返回的 shared_ptr 将为空)。
5-6) const_cast
7-8) reinterpret_cast
这些函数的行为未定义,除非从 U* 到 T* 的对应转型为良式:
1-2) 行为未定义,除非 static_cast
3-4) 行为未定义,除非 dynamic_cast
5-6) 行为未定义,除非 const_cast
7-8) 行为未定义,除非 reinterpret_cast
| 调用右值重载 (2,4,6,8) 后, | (C++20 起) |
| r | - | 要转换的指针 |
表达式 std::shared_ptr
- template< class T, class U >
- std::shared_ptr<T> static_pointer_cast( const std::shared_ptr<U>& r ) noexcept
- {
- auto p = static_cast<typename std::shared_ptr<T>::element_type*>(r.get());
- return std::shared_ptr<T>(r, p);
- }
- template< class T, class U >
- std::shared_ptr<T> dynamic_pointer_cast( const std::shared_ptr<U>& r ) noexcept
- {
- if (auto p = dynamic_cast<typename std::shared_ptr<T>::element_type*>(r.get())) {
- return std::shared_ptr<T>(r, p);
- } else {
- return std::shared_ptr<T>();
- }
- }
- template< class T, class U >
- std::shared_ptr<T> const_pointer_cast( const std::shared_ptr<U>& r ) noexcept
- {
- auto p = const_cast<typename std::shared_ptr<T>::element_type*>(r.get());
- return std::shared_ptr<T>(r, p);
- }
- #include <iostream>
- #include <memory>
-
- struct BaseClass {};
-
- struct DerivedClass : BaseClass
- {
- void f() const
- {
- std::cout << "Hello World!\n";
- }
- ~DerivedClass() // 注意:它不是虚的
- {
- std::cout << "~DerivedClass\n";
- }
- };
-
- int main()
- {
- std::shared_ptr<BaseClass> ptr_to_base(std::make_shared<DerivedClass>());
-
- // ptr_to_base->f(); // 错误不会编译: BaseClass 无名为 'f' 的成员
-
- std::static_pointer_cast<DerivedClass>(ptr_to_base)->f(); // OK
- // (构造临时 shared_ptr ,然后调用 operator-> )
-
- static_cast<DerivedClass*>(ptr_to_base.get())->f(); // 亦 OK
- // (直接转型,不构造临时 shared_ptr )
- }

p 的删除器 std::get_deleter
- template< class Deleter, class T >
- Deleter* get_deleter( const std::shared_ptr<T>& p ) noexcept;(C++11 起)
访问 p 的删除器。若共享指针 p 占有无 cv 限定 Deleter 类型的删除器(例如,若它以接收删除器为参数的构造函数之一创建),则返回指向删除器的指针。否则,返回空指针。
| p | - | 需要访问其删除器的共享指针 |
指向被占有删除器的指针或 nullptr 。只要至少还有一个 shared_ptr 实例占有返回的指针,它就合法。
返回的指针可能比最后一个 shared_ptr 的生存期更持久,例如,还剩下 std::weak_ptr 时且实现在销毁整个控制块前不销毁删除器。
- #include <iostream>
- #include <memory>
-
- struct Foo
- {
- int i;
- };
- void foo_deleter(Foo * p)
- {
- std::cout << "foo_deleter called!\n";
- delete p;
- }
-
- int main()
- {
- std::shared_ptr<int> aptr;
-
- {
- // 创建拥有一个 Foo 和删除器的 shared_ptr
- auto foo_p = new Foo;
- std::shared_ptr<Foo> r(foo_p, foo_deleter);
- aptr = std::shared_ptr<int>(r, &r->i); // 别名使用构造函数
- // aptr 现在指向 int ,但管理整个 Foo
- } // r 被销毁(不调用删除器)
-
- // 获得指向删除器的指针:
- if (auto del_p = std::get_deleter<void(*)(Foo*)>(aptr))
- {
- std::cout << "shared_ptr
owns a deleter\n" ; - if (*del_p == foo_deleter)
- {
- std::cout << "...and it equals &foo_deleter\n";
- }
- }
- else
- {
- std::cout << "The deleter of shared_ptr
is null!\n" ; - }
- } // 于此调用删除器
