| C++標準庫 |
| --- |
| 
容器
* `array`
* `bitset`
* `deque`
* `forward\_list`
* `list`
* `map`
* `multimap`
* `multiset`
* `queue`
* `set`
* `stack`
* `unordered\_map`
* `unordered\_multimap`
* `unordered\_set`
* `unordered\_multiset`
* `vector`

 |
| 
输入/输出流
* `fstream`
* `iomanip`
* `ios`
* `iosfwd`
* `iostream`
* `istream`
* `ostream`
* `sstream`
* `streambuf`

 |
| 
字符串及字符处理
* `charconv`
* `codecvt`
* `regex`
* `string`
* `string\_view`

 |
| 
工具
* `algorithm`
* `any`
* `chrono`
* `execution`
* `filesystem`<>
* `functional`
* `initializer\_list`
* `iterator`
* `locale`
* `optional`
* `system\_error`
* `|tuple`
* `type\_index`
* `typeinfo`
* `type\_traits`
* `utility`
* `valarray`
* `variant`

 |
| 
多线程与并发
* `atomic`
* `condition\_variable`
* `future`
* `mutex`
* `shared\_mutex`
* `thread`

 |
| 
数值
* `complex`
* `limits`
* `numeric`
* `random`
* `ratio`

 |
| 
C++异常处理
* `exception`
* `stdexcept`

 |
| 
内存
* `new`
* `memory`
* `memory\_resource`
* `scoped\_allocator`

 |
| 
C標準函式庫
* `cassert`
* `ccomplex`
* `cctype`
* `cerrno`
* `cfenv`
* `cfloat`
* `cinttypes`
* `ciso646`
* `climits`
* `clocale`
* `cmath`
* `csetjmp`
* `csignal`
* `cstdalign`
* `cstdarg`
* `cstdbool`
* `cstddef`
* `cstdint`
* `cstdio`
* `cstdlib`
* `cstring`
* `ctime`
* `ctgmath`
* `cuchar`
* `cwchar`
* `cwctype`

 |
| * 
* 论
* 编
 |

**memory** 是C++標準程式庫中的一個头文件，定义了C++标准中的智能指针、内存分配器（allocator）、与垃圾回收有关的函数、临时性的申请与释放动态内存的函数、在内存上创建（构造）对象的函数等等。

运算符
---

* operator!= 测试allocator、智能指针是否不等
* operator==测试allocator、智能指针是否相等
* operator>= 测试智能指针所指向的数据对象地址
* operator< 测试智能指针所指向的数据对象地址
* operator<= 测试智能指针所指向的数据对象地址
* operator> 测试智能指针所指向的数据对象地址
* operator<< 向流对象输出智能指针所指向的数据对象地址

智能指针
----

智能指针是指当指针对象的生命期结束析构时，同时把指针所指的对象也delete或者引用计数减1。

### unique\_ptr

unique\_ptr是个类模板。unique\_ptr指针对象独占式地引用所指的数据对象。不能复制构造（copy ctor），也不能复制赋值，也就是对其无法进行复制，不能得到指向同一个对象的两个unique\_ptr；但是可以移动构造和移动赋值。当unique\_ptr指针对象离开其作用域，生命期结束时，自动使用内部给定的删除器（deleter）delete所指向的数据对象。unique\_ptr十分依赖于右值引用和移动语义。

```
template<class Type, class Del = default\_delete<Type> >
 class unique\_ptr {
public:
 typedef Type element\_type; //指针基类型
 typedef Del deleter\_type; //析构类型
 typedef T1 pointer; //指针类型 为Del::pointer，否则为Type \*
//构造函数
 unique\_ptr (); //11 空指针
 unique\_ptr (nullptr\_t \_Nptr); //22 空指针
 explicit unique\_ptr (pointer \_Ptr); //33
 unique\_ptr (pointer \_Ptr, typename conditional<is\_reference<Del>::value, Del,typename add\_reference<const Del>::type>::type \_Deleter); //44
 unique\_ptr (pointer \_Ptr,typename remove\_reference<Del>::type&& \_Deleter); //55
 unique\_ptr (unique\_ptr&& \_Right); //66
 template<class Type2, Class Del2> unique\_ptr (unique\_ptr<Type2, Del2>&& \_Right); //77
//析构函数
 ~unique\_ptr ();
//
 unique\_ptr& operator= (unique\_ptr&& \_Right); //右值赋值
 template<class Type2, Class Del2> unique\_ptr& operator= (unique\_ptr<Type2, Del2>&& \_Right);//右值赋值
 void swap (unique\_ptr& \_Right); //交换两个unique\_ptr对象的内容
 pointer release (); //在stored\_ptr中存储pointer的新的值，并返回前一个值，用于放弃对所指数据对象的独占
 void reset (pointer \_Ptr = pointer() ); //delete当前拥有的资源并接受新的资源

 pointer get () const; //返回stored\_ptr
 Type& operator\* () const; //返回\*stored\_ptr
 pointer operator-> () const; //返回stored\_ptr
 Del& get\_deleter (); //返回stored\_deleter的引用
 const Del& get\_deleter () const; //返回stored\_deleter
 explicit operator bool () const; //get() != pointer() 的值

 unique\_ptr(const unique\_ptr& \_Right) = delete;
 unique\_ptr& operator=(const unique\_ptr& \_Right) = delete;

private:
 pointer stored\_ptr; // exposition only
 Del stored\_deleter; // exposition only
 };

```

unique\_ptr的主要用途有：

1. 实现资源获取即初始化（RAII）。当程序发生异常时，异常处理机制的栈展开（stack unwinding）会销毁局部变量，包括unique\_ptr对象，从而自动释放资源。
2. 实现右值移动语义。例如，unique\_ptr类型可作为函数的返回值类型，采用了隐式地移动赋值。
3. 在容器中保存unique\_ptr对象。需要显式地移动赋值，即通过std::move()。

### shared\_ptr

shared\_ptr是一个类模板，包装了使用引用计数的智能指针。当shared\_ptr在退出其作用域、生命期结束时，析构函数或自动对所指内存数据对象的引用计数减去1。如果内存数据对象的引用计数为0，则会被自动delete。指向同一资源的shared\_ptr共同拥有一个控制块，其中保存了shared\_ptr的引用计数、指向这一资源的weak\_ptr的数目、资源的析构器（deleter ）地址、对该控制块的可定制的allocator。

```
template<class Ty>
 class shared\_ptr {
public:
 typedef Ty element\_type; //指针基类型
//构造函数
 shared\_ptr(); //11 空指针
 shared\_ptr(nullptr\_t); //22 空指针
 shared\_ptr(const shared\_ptr& sp); //33 拷贝构造
 shared\_ptr(shared\_ptr&& sp); //44 右值移动构造
 template<class Other> explicit shared\_ptr(Other \* ptr); //55 由其他指针初始化，构造失败时自动调用delete ptr
 template<class Other, class D> shared\_ptr(Other \* ptr, D dtor); //66 由其他指针初始化，dtor是个可调用的函数对象，构造失败时自动调用dtor(ptr)
 template<class D> shared\_ptr(nullptr\_t, D dtor); //77 空指针，并指定deleter
 template<class Other, class D, class A> shared\_ptr(Other \*ptr, D dtor, A alloc);//88 alloc管理shared\_ptr控制块的内存分配与释放，构造失败时自动调用dtor(ptr)
 template<class D, class A> shared\_ptr(nullptr\_t, D dtor, A alloc);//99 空指针
 template<class Other> shared\_ptr(const shared\_ptr<Other>& sp); //0A 拷贝构造+类型转换
 template<class Other> shared\_ptr(const shared\_ptr<Other>&& sp); //0B 移动构造+类型转换
 template<class Other> explicit shared\_ptr(const weak\_ptr<Other>& wp); //0C 由弱指针拷贝构造
 template<class Other> shared\_ptr(auto\_ptr<Other>& ap); //0D 由auto\_ptr指针拷贝构造
 template<class Other, class D> shared\_ptr(unique\_ptr<Other, D>&& up); //0E 由unique\_ptr移动构造
 template<class Other> shared\_ptr(const shared\_ptr<Other>& sp, Ty \*ptr); //0F 
 template<class Other, class D>shared\_ptr(const unique\_ptr<Other, D>& up) = delete;//10 禁用const unique\_ptr作为移动构造函数
 ~shared\_ptr(); // 析构函数
 shared\_ptr& operator=(const shared\_ptr& sp); //赋值运算符
 template<class Other> shared\_ptr& operator=(const shared\_ptr<Other>& sp); //类型转换的赋值运算符
 shared\_ptr& operator=(shared\_ptr&& sp); //右值引用的移动语义
 template<class Other> shared\_ptr& operator=(shared\_ptr<Other>&& sp); //右值引用+类型转换
 template<class Other> shared\_ptr& operator=(auto\_ptr< Other >&& ap); //右值引用+auto\_ptr类型转换
 template <class Other, class D> shared\_ptr& operator=(const unique\_ptr< Other, D>& up) = delete; //禁止const型unique\_ptr移动赋值给shared\_ptr
 template <class Other, class D> shared\_ptr& operator=(unique\_ptr<Other, D>&& up);//右值引用的移动语义+类型转换
 void swap(shared\_ptr& sp); //交换两个指针的内容
//reset成员函数，把当前指向的数据对象的引用计数减1，然后指向参数表中新的数据对象
 void reset(); 
 template<class Other> void reset(Other \*ptr);
 template<class Other, class D> void reset(Other \*ptr, D dtor);
 template<class Other, class D, class A> void reset(Other \*ptr, D dtor, A alloc);

 Ty \*get() const; //返回所指向的数据对象的地址
 Ty& operator\*() const; //返回所指向的数据对象
 Ty \*operator->() const; //返回所指向的数据对象的地址
 long use\_count() const; //返回引用计数值
 bool unique() const; //判断是否独占引用数据对象
 operator bool() const; //判断是否指向了一个数据对象

 template<class Other> bool owner\_before(shared\_ptr<Other> const& ptr) const;
 template<class Other> bool owner\_before(weak\_ptr<Other> const& ptr) const;
 template<class D, class Ty> D\* get\_deleter(shared\_ptr<Ty> const& ptr);
};

```

### weak\_ptr

弱指针weak\_ptr用于指向、但不拥有（即不参加引用计数）由shared\_ptr管理的资源。弱指针并不直接提供对资源的访问。应该通过shared\_ptr来访问资源。当资源的引用计数为0（所有拥有该资源的shared\_ptr对象都已被销毁），该资源将被delete，这时如果仍然有弱指针指向该资源，则该弱指针将变为expired状态。这实际上避免了资源的循环引用计数。对于循环的引用计数，如果把其中的一个shared\_ptr的指针指向改为weak\_ptr的指针指向，即打破了循环引用。

```
template<class Ty> class weak\_ptr {
public:
 typedef Ty element\_type; //指针基类型
//构造函数
 weak\_ptr(); //空指针
 weak\_ptr(const weak\_ptr&); //拷贝构造
 template<class Other> weak\_ptr(const weak\_ptr<Other>&); //类型转换的拷贝构造
 template<class Other> weak\_ptr(const shared\_ptr<Other>&); //从shared\_ptr拷贝构造
//赋值运算符
 weak\_ptr& operator=(const weak\_ptr&);
 template<class Other> weak\_ptr& operator=(const weak\_ptr<Other>&);
 template<class Other> weak\_ptr& operator=(shared\_ptr<Other>&);

 void swap(weak\_ptr&); //交换对象的内容
 void reset(); //放弃指向资源，当前对象变为空的弱指针

 long use\_count() const; //返回资源的引用计数
 bool expired() const; //判断指向的资源是否还存在（或已经被释放）
 shared\_ptr<Ty> lock() const; // 获取对资源的专属拥有
 };

```

### auto\_ptr

auto\_ptr，即自动指针，在C++11标准是过时的类模板。

其他Helper类
---------

### default\_delete

作为使用`operator new`分配内存的unique\_ptr对象的deleter。有两种形式：

* 为指针： template< class T > struct default\_delete; 函数调用成员运算符调用delete
* 为指针数组： template< class T > struct default\_delete<T[]>; 函数调用成员运算符模板调用delete[]

示例：

```
#include <memory>
#include <vector>
#include <algorithm>
 
int main()
{
// {
// std::shared\_ptr<int> shared\_bad(new int[10]);
// } // the destructor calls delete, undefined behavior
 
 {
 std::shared\_ptr<int> shared\_good(new int[10], std::default\_delete<int[]>
());
 } // the destructor calls delete[], ok
 
 {
 std::unique\_ptr<int> ptr(new int(5));
 } // unique\_ptr<int> uses default\_delete<int>
 
 {
 std::unique\_ptr<int[]> ptr(new int[10]);
 } // unique\_ptr<int[]> uses default\_delete<int[]>
 
 // default\_delete can be used anywhere a delete functor is needed
 std::vector<int\*> v;
 for(int n = 0; n < 100; ++n)
 v.push\_back(new int(n));
 std::for\_each(v.begin(), v.end(), std::default\_delete<int>());
}

```

### allocator

条目：分配器 (C++)
allocator是STL中非常常用的类模板，用于定制内存的分配、释放、管理。目的是封装STL容器在内存管理上的低层细节，所以用户程序不应该直接调用allocator去管理内存，除非是正在定制容器。allocator将内存的分配与对象的构造初始化解耦，分别用allocate、construct两个成员函数完成；同样将内存的释放与对象的析构销毁解耦，分别用deallocat、destroy两个成员函数完成。自定义的allocator的实现，必须满足C++11标准的17.6.3.5节中的"Table 28 —— Allocator requirements"，简单说就是要在类中定义若干类型名、模板成员名、成员函数、运算符函数。`<memory>`中定义的allocator类模板做一些使用全局malloc/free函数表达式的内存的分配、释放的平常操作：

```
template<class \_Ty> class allocator : public \_Allocator\_base<\_Ty>
 { 
public:
/\*类型定义。容器类常常直接从它的allocator提取这些类型—— \*/
typedef \_Allocator\_base<\_Ty> \_Mybase; //基类型
 typedef typename \_Mybase::value\_type value\_type;//值类型
 typedef value\_type \_FARQ \*pointer; //指针类型
 typedef value\_type \_FARQ& reference; //引用类型
 typedef const value\_type \_FARQ \*const\_pointer; //常量指针类型
 typedef const value\_type \_FARQ& const\_reference;//常量引用类型
 typedef size\_t size\_type; //size类型
 typedef ptrdiff\_t difference\_type; //地址差值类型
/\*类型操作函数： \*/ 
 template<class \_Other>
 struct rebind //用于'''重绑定'''的成员模板： convert this type to allocator<\_Other>。
 //因为容器类需要动态申请内存的往往不是value\_type，而是诸如List Node这样的其他类型
 { 
 typedef allocator<\_Other> other;
 };

 pointer address(reference \_Val) const
 { // 把mutuable引用变换为地址返回
 return ((pointer) &(char&)\_Val);
 }

 const\_pointer address(const\_reference \_Val) const
 { //把只读引用变换为只读地址返回
 return ((const\_pointer) &(char&)\_Val);
 }
/\*构造函数：\*/ 
 allocator() throw( )
 { //缺省构造，不抛出异常
 }

 allocator(const allocator<\_Ty>&) throw()
 { // 空的拷贝构造
 }

 template<class \_Other>
 allocator(const allocator<\_Other>&) throw()
 { //从相关的allocator做拷贝构造，内容为空
 }

 template<class \_Other>
 allocator<\_Ty>& operator=(const allocator<\_Other>&)
 { //从相关的allocator做拷贝赋值运算符，内容为空
 return (\*this);
 }
/\*以下为业务函数： \*/
 void deallocate(pointer \_Ptr, size\_type) //释放内存，并不析构对象。第二个参数为元素的项数
 { // deallocate object at \_Ptr, ignore size 
 ::operator delete(\_Ptr);
 }

 pointer allocate(size\_type \_Count) //获取内存资源，并不调用对象的构造函数
 { // allocate array of \_Count elements
 return (\_Allocate(\_Count, (pointer)0)); 
 }

 pointer allocate(size\_type \_Count, const void \_FARQ \*)
 { // allocate array of \_Count elements, ignore hint 为高性能而设计的allocator可能会利用第二个参数的提示
 return (allocate(\_Count));
 }

 void construct(pointer \_Ptr, const \_Ty& \_Val) // construct object at \_Ptr with value \_Val 
 { //实际上调用了"带位置的new运算符表达式"，实现在特定位置上调用构造函数。 
 \_Construct(\_Ptr, \_Val);
 }

 void construct(pointer \_Ptr, \_Ty&& \_Val) //construct object at \_Ptr with right-value \_Val
 { 实际上调用了"带位置的new运算符表达式"，以及右值完美转发，实现在特定位置上调用构造函数。
 ::new ((void \_FARQ \*)\_Ptr) \_Ty(\_STD forward<\_Ty>(\_Val));
 }

 template<class \_Other>
 void construct(pointer \_Ptr, \_Other&& \_Val) // construct object at \_Ptr with value \_Val， 带类型转换
 { 
 ::new ((void \_FARQ \*)\_Ptr) \_Ty(\_STD forward<\_Other>(\_Val));
 }

 void destroy(pointer \_Ptr)
 { // 摧毁在地址 \_Ptr的对象，但不释放内存
 \_Destroy(\_Ptr);
 }

 \_SIZT max\_size() const \_THROW0()
 { // 估计allocator能分配的数据对象的最大可能数目
 \_SIZT \_Count = (\_SIZT)(-1) / sizeof (\_Ty);
 return (0 < \_Count ? \_Count : 1);
 }
};

```

### allocator\_traits

allocator\_traits是对allocator的包装。

### bad\_weak\_ptr

bad\_weak\_ptr是个异常类。在用弱指针拷贝构造共享指针时，如果弱指针是expired，那么拷贝构造函数抛出bad\_weak\_ptr异常。

### enable\_shared\_from\_this

enable\_shared\_from\_this是一个helper类模板，用于作为数据类的基类。当数据类的对象已经被shared\_ptr所拥有，如果需要从该数据类对象获得其shared\_ptr指针，就需要调用作为基类的enable\_shared\_from\_this的成员函数`shared_from_this`。例如：

```
struct Data : public enable\_shared\_from\_this<Data> { };

int main() {
 shared\_ptr<Data> a (new Data);
 Data& r = \*a;
 shared\_ptr<Data> b = r.shared\_from\_this(); 
}

```

在上例中，b与a共同拥有对数据类对象的同一套引用计数，因此是正确的。如果如此构造b：

`shared_ptr b( &r);`
则对同一个数据类对象，弄出了两套引用计数。这会导致当一套引用计数变为0而销毁数据类对象时，另外一套引用计数的shared\_ptr成为"悬空"的错误。

Microsoft Visual C++ 2010是在enable\_shared\_from\_this类模板中定义一个数据类型`_EStype`。shared\_ptr的对象在调用构造函数时，最后将调用一个函数\_Enable\_shared(\_Ty \*\_Ptr, \_Ref\_count\_base \*\_Refptr），其中第一个参数是数据类对象的指针，第二个参数是引用计数控制块的指针。利用模板元编程的参数推导的特性，编译器选择\_Enable\_shared，或是匹配下述模板函数

`template<class _Ty> inline void _Enable_shared(_Ty *_Ptr, _Ref_count_base *_Refptr, typename _Ty::_EStype * = 0)`
或是匹配下述普通函数

`inline void _Enable_shared(const volatile void *, const volatile void *) { }`
前者把enable\_shared\_from\_this类中把一个弱指针指向了shared\_ptr的引用计数控制块。从而实现了enable\_shared\_from\_this类的语义。

### pointer\_traits

pointer\_traits是一个类模板，描述指针类型所需要的一些类型的定义。

* 成员类型
	+ pointer 指针类型
	+ element\_type 指针的基类型
	+ difference\_type 一般是std::ptrdiff\_t
	+ rebind 成员类模板，指向需要绑定的其它类型
* 静态成员函数
	+ pointer\_to 从引用类型返回其相应的指针类型，一般为std::addressof(r)

### raw\_storage\_iterator

raw\_storage\_iterator是个类模板，用于表示指向内存的一个前向迭代器。其赋值运算符在当前所指向内存上调用值类型的构造函数，生成一个对象。

函数
--

* void\* align( std::size\_t alignment,std::size\_t size,void\*& ptr,std::size\_t& space );在一块内存（ptr所指）中，按照对齐要求slignment，找到一块长度为size的，并重置ptr为该内存起始地址，space为该内存长度。
* allocate\_shared 这是shared\_ptr的工厂函数，指定内存分配器allocator与数据对象的初始化参数，创建数据对象及shared\_ptr。
* const\_pointer\_cast 用于shared\_ptr对象的const的类型转换。
* declare\_no\_pointers 用于垃圾回收。告知垃圾收集器在指定的内存范围内不含可跟踪的指针。
* declare\_reachable 用于垃圾回收。令垃圾收集器知道参数指针是指向一块声明为可达的动态分配内存。声明为可达的（declared reachable）完全对象，是指该对象作为形参所指，declare\_reachable调用的次数超过undeclare\_reachable调用次数。声明为可达的一块动态分配内存不能被垃圾收集器释放，即使它看起来没有可达的访问方法。
* dynamic\_pointer\_cast 对shared\_ptr对象的运行时动态转换类型。
* get\_deleter 返回shared\_ptr对象的deleter。
* get\_pointer\_safety 用于垃圾回收。返回当前的垃圾回收器采用的指针类型。
* get\_temporary\_buffer 对给定类型、给定对象数目，分配一块临时的内存存储。
* make\_shared 这是shared\_ptr的工厂函数，使用给定的数据对象的初始化参数，创建数据对象及shared\_ptr。
* owner\_less 混合比较shared\_ptr对象与weak\_ptr对象的序关系。
* pointer\_safety 用于垃圾回收。是`get_pointer_safety`的返回值的枚举类型。
* return\_temporary\_buffer 释放由`get_temporary_buffer`分配的临时性的内存块。
* static\_pointer\_cast 编译时静态转换shared\_ptr的值类型。
* swap 交换两个shared\_ptr对象或交换两个weak\_ptr对象.
* undeclare\_no\_pointers 用于垃圾回收。告诉垃圾回收器，在指定范围的内存中，存着可跟踪指针。
* undeclare\_reachable 用于垃圾回收。告诉垃圾回收器，被形参指针所指的动态分配内存块，撤销一次declare\_reachable操作。如果动态分配内存块上没有declare\_reachable操作，则垃圾收集器如果判断它已经是不可达的状态（即没有手段访问这块内存）就可把它当垃圾回收。
* uninitialized\_copy 把输入iterator所给出的一个内存范围内的对象数组的每个元素，逐个拷贝构造到前向的目标iterator所指的内存上。
* uninitialized\_copy\_n 把输入iterator所给出的一个内存地址开始的对象数组的n个元素，逐个拷贝构造到前向的目标iterator所指的内存上。
* uninitialized\_fill 在输入iterator所给出的一个内存范围内，用给定的对象去拷贝构造多个对象。
* uninitialized\_fill\_n 在输入iterator所给出的一个内存开始地址处，用给定的对象去拷贝构造指定的n个对象。

例子
--

### 共享指针

```
#include <memory>
#include <iostream>
class Test
{
public:
 Test()
 {
 std::cout << "Test()" << std::endl;
 }
 ~Test()
 {
 std::cout << "~Test()" << std::endl;
 }
};
int main()
{
 std::shared\_ptr<Test> p1 = std::make\_shared<Test>();
 std::cout << "1 ref:" << p1.use\_count() << std::endl;
 {
 std::shared\_ptr<Test> p2 = p1;
 std::cout << "2 ref:" << p1.use\_count() << std::endl;
 }
 std::cout << "3 ref:" << p1.use\_count() << std::endl;
 return 0;
}

```

### 弱指针例子

```
#include <iostream>
#include <memory>
class TestB;
class TestA
{
public:
 TestA()
 {
 std::cout << "TestA()" << std::endl;
 }
 void ReferTestB(std::shared\_ptr<TestB> test\_ptr)
 {
 m\_TestB\_Ptr = test\_ptr;
 }
 void TestWork()
 {
 std::cout << "~TestA::TestWork()" << std::endl;
 }
 ~TestA()
 {
 std::cout << "~TestA()" << std::endl;
 }
private:
 std::weak\_ptr<TestB> m\_TestB\_Ptr;
};
class TestB
{
public:
 TestB()
 {
 std::cout << "TestB()" << std::endl;
 }
 void ReferTestB(std::shared\_ptr<TestA> test\_ptr)
 {
 m\_TestA\_Ptr = test\_ptr;
 }
 void TestWork()
 {
 std::cout << "~TestB::TestWork()" << std::endl;
 }
 ~TestB()
 {
 ////把std::weak\_ptr类型转换成std::shared\_ptr类型
 std::shared\_ptr<TestA> tmp = m\_TestA\_Ptr.lock();
 tmp->TestWork();
 std::cout << "2 ref a:" << tmp.use\_count() << std::endl;
 std::cout << "~TestB()" << std::endl;
 }
 std::weak\_ptr<TestA> m\_TestA\_Ptr;
};
int main()
{
 std::shared\_ptr<TestA> ptr\_a = std::make\_shared<TestA>();
 std::shared\_ptr<TestB> ptr\_b = std::make\_shared<TestB>();
 ptr\_a->ReferTestB(ptr\_b);
 ptr\_b->ReferTestB(ptr\_a);
 std::cout << "1 ref a:" << ptr\_a.use\_count() << std::endl;
 std::cout << "1 ref b:" << ptr\_a.use\_count() << std::endl;
 return 0;
}

```

### 独占指针的例子

```
#include <iostream>
int main()
{
 std::unique\_ptr<int> pInt;
 pInt.reset(new int());
 int \*p = pInt.release(); //释放所有权
 //由于unique\_ptr有std::unique\_ptr<T[]>的重载函数，所以它可以用来管理数组资源
 std::unique\_ptr<int[]> pArray(new int[3]{1,3,3}); 
}

```

参考文献
----

1. ↑ .  [2013-08-10]. （原始内容存档于2020-07-31）.
2. ↑  C++11标准20.6.4-1

* 《Boost程序库完全开发指南——深入C++"准"标准库》第3章 内存管理 3.4 shared\_ptr 作者: 罗剑锋 电子工业出版社 2010年9月版 ISBN 9787121115776