定义于头文件
template< class T > class shared_ptr; (C++11 起)
std::shared_ptr<T>::get
- T* get() const noexcept; (C++17 前)
- element_type* get() const noexcept; (C++17 起)
返回存储的指针。
(无)
存储的指针。
shared_ptr
可能在存储指向一个对象的指针时共享另一对象的所有权。 get()
返回存储的指针,而非被管理指针。
- #include <iostream>
- #include <memory>
- #include <string>
-
- void output(std::string msg, int const* pInt)
- {
- std::cout << msg << *pInt << "\n";
- }
-
- int main()
- {
- int* pInt = new int(42);
- std::shared_ptr<int> pShared = std::make_shared<int>(42);
-
- output("Naked pointer ", pInt);
- // output("Shared pointer ", pShared); // 编译错误
- output("Shared pointer with get() ", pShared.get());
-
- delete pInt;
- }
- std::shared_ptr<T>::operator*,
- std::shared_ptr<T>::operator->
- T& operator*() const noexcept; (1)
-
- T* operator->() const noexcept; (2)
解引用所存储的指针。若存储的指针为空,则行为未定义。
(无)
1) 解引用存储的指针所得的结果,即 *get()
2) 存储的指针,即 get()
T
是(可有 cv 限定的) void 类型时,是否声明函数 (1) 是未指定的。
| (C++17 起) |
以上情况下,若声明函数,则其返回类型是未指定的,但保证函数声明合法,函数定义未必合法。这使得 std::shared_ptr
- #include <iostream>
- #include <memory>
-
- struct Foo
- {
- Foo(int in) : a(in) {}
- void print() const
- {
- std::cout << "a = " << a << '\n';
- }
- int a;
- };
-
- int main()
- {
- auto ptr = std::make_shared<Foo>(10);
- ptr->print();
- (*ptr).print();
- }
std::shared_ptr<T>::use_count
long use_count() const noexcept;
返回管理当前对象的不同 shared_ptr
实例(包含 this )数量。若无管理对象,则返回 0 。
多线程环境下, use_count 返回的值是近似的(典型实现使用 memory_order_relaxed 加载)
(无)
管理当前对象的 shared_ptr
实例数量,或若无被管理对象则为 0 。
常用使用包括
use_count
返回零,则智能指针为空且不管理对象(无论被存储指针是否为空)。多线程环境下,这不隐含被管理对象的析构函数已完成。use_count
返回 1 ,则无其他拥有者。(被弃用成员函数 unique() 为此使用情况提供。)多线程环境中,这不隐含对象可以安全修改,因为先前拥有者对被管理对象的访问可能未完成,而因为新的共享拥有者可以同时引入,例如用 std::weak_ptr::lock 。- #include <memory>
- #include <iostream>
-
- void fun(std::shared_ptr<int> sp)
- {
- std::cout << "fun: sp.use_count() == " << sp.use_count() << '\n';
- }
-
- int main()
- {
- auto sp1 = std::make_shared<int>(5);
- std::cout << "sp1.use_count() == " << sp1.use_count() << '\n';
-
- fun(sp1);
- }
std::shared_ptr::operator bool
explicit operator bool() const noexcept;
检查 *this 是否存储非空指针,即是否有 get() != nullptr 。
(无)
若 true 存储非空指针则为 *this ,否则为 false 。
空 shared_ptr (其中 use_count() == 0 )可能存储能以 get()
访问的非空指针,例如若它以别名使用构造函数创建。
- #include <iostream>
- #include <memory>
-
- void report(std::shared_ptr<int> ptr)
- {
- if (ptr) {
- std::cout << "*ptr=" << *ptr << "\n";
- } else {
- std::cout << "ptr is not a valid pointer.\n";
- }
- }
-
- int main()
- {
- std::shared_ptr<int> ptr;
- report(ptr);
-
- ptr = std::make_shared<int>(7);
- report(ptr);
- }
std::shared_ptr<T>::owner_before
- template< class Y >
- bool owner_before( const shared_ptr<Y>& other) const noexcept;
-
- template< class Y >
- bool owner_before( const std::weak_ptr<Y>& other) const noexcept;
以实现定义的基于拥有者(与基于值相反)顺序,检查此 shared_ptr
是否先于 other
。二个智能指针仅若都占有同一对象或均为空才比较相等,即使由 get() 获得的指针不同(例如因为它们指向同一对象中的不同子对象)。
此顺序用于令共享和弱指针可用作关联容器中的关键,通常经由 std::owner_less 。
other | - | 要比较的 std::shared_ptr 或 std::weak_ptr |
若 *this 前于 other
则为 true ,否则为 false 。常见实现比较控制块的地址。
- #include <iostream>
- #include <memory>
-
- struct Foo
- {
- int n1;
- int n2;
- Foo(int a, int b) : n1(a), n2(b) {}
- };
- int main()
- {
- auto p1 = std::make_shared<Foo>(1, 2);
- std::shared_ptr<int> p2(p1, &p1->n1);
- std::shared_ptr<int> p3(p1, &p1->n2);
-
- std::cout << std::boolalpha
- << "p2 < p3 " << (p2 < p3) << '\n'
- << "p3 < p2 " << (p3 < p2) << '\n'
- << "p2.owner_before(p3) " << p2.owner_before(p3) << '\n'
- << "p3.owner_before(p2) " << p3.owner_before(p2) << '\n';
-
- std::weak_ptr<int> w2(p2);
- std::weak_ptr<int> w3(p3);
- std::cout
- // << "w2 < w3 " << (w2 < w3) << '\n' // won't compile
- // << "w3 < w2 " << (w3 < w2) << '\n' // won't compile
- << "w2.owner_before(w3) " << w2.owner_before(w3) << '\n'
- << "w3.owner_before(w2) " << w3.owner_before(w2) << '\n';
-
- }