智能指针之shared_ptr基本概述

1.shared_ptr允许有多个指针指向同一个对象,unique_ptr独占所指向的对象。

2.类似于vector,智能指针也是模板。创建智能指针:

1 shared_ptr<string> p1;        //指向string的shared_ptr
2 shared_ptr<list<int>> p2;   //指向int的list的shared_ptr

使用make_shared函数分配一个对象并初始化它,make_shared函数返回一个指向此对象的shared_ptr:

1 //指向值为42的int的shared_ptr
2 shared_ptr<int> p3 = make_shared<int>(42);
3 
4 //指向一个值为“999”的string
5 shared_ptr<string> p4 = make_shared<string>("999");
6 
7 //指向一个值初始化的int,即值为0
8 shared_ptr<int> p5 = make_shared<int>();

3.我们可以认为每个share_ptr都有一个关联的计数器,通常称为引用计数(reference count)。无论何时我们拷贝一个shared_ptr,计数器都会递增。

例如这些都会使所关联的计数器递增

(1)当用一个shared_ptr初始化另外一个shared_ptr

(2)将它作为参数传递给另外一个函数

(3)作为函数的返回值

例如这些操作会使计数器都会递减:

(1)给share_ptr赋新的值

(2)share_ptr被销毁

(3)局部的share_ptr离开作用域

 以下通过两个例子来讲解计数的规则:

1 shared_ptr<int> p = make_shared<int>(42);
2 shared_ptr<int> q(p);                        //此对象现在有两个引用者,计数为2
3 shared_ptr<int> r = make_shared<int>(42);   //r现在有一个计数
4 r = q;                                        //r现在指向q所指向的对象了,所以第二个42被销毁,因为计数为0
5                                                 //而第一个计数为3
6 cout << "p所指对象的引用计数为:" << p.use_count() << endl;

 再比如下一个程序:

 1 shared_ptr<Foo> factory(T arg)
 2 {
 3     return make_shared<Foo>(arg);        //返回一个shared_ptr<Foo>
 4 }
 5 void use_factory(T arg)
 6 {
 7     shared_ptr<Foo> p = factory(arg);   //此时p的计数值为1
 8 }        //由于p是局部变量,出了这个函数,计数值先递减,然后检查计数值,发现为0,销毁p的对象,内存被释放掉
 9 shared_ptr<Foo> use_factory(T arg)
10 {
11     shared_ptr<Foo> p = factory(arg);   //此时p的计数值为1
12     return p;                            //返回了一个智能指针类,计数值加1,为2
13 }    //离开了作用域,但是指向的内存不会被释放,因为还有对象的引用计数不是0

 4.当指向的最后一个shared_ptr被销毁时,是调用析构函数来完成销毁工作的,析构函数会先递减它所指向的对象的引用计数,再检查引用计数值,如果引用计数变为0,那么shared_ptr析构函数就会销毁对象,并释放它占用的内存。

附:shared_ptr支持的一些操作:

原文地址:https://www.cnblogs.com/love-jelly-pig/p/9067843.html