一、shared_ptr的使用
前文写到unique_ptr不支持拷贝,所以shared_ptr应用而生,shared_ptr可很好的支持拷贝与赋值
1.1代码演示:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
#include "shared_ptr.h"
struct A
{
A(int a=0)
:_a(a)
{
cout << "A(int a=0)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
int _a;
};
void test1()
{
shared_ptr<A> sp1(new A(1));
shared_ptr<A> sp2(new A(2));
shared_ptr<A> sp3(new A(3));
shared_ptr<A> sp4(sp1);
sp2 = sp4;
sp1 = sp3;
cout << ++sp2->_a << endl;
cout << ++sp1->_a << endl;
}
int main()
{
test1();
return 0;
}
1.2运行结果:
那么shared_ptr是如何实现智能指针的拷贝与赋值呢?
二、shared_ptr的模拟实现
2.1实现之前我们先对上面程序运行结果进行逐条分析:
运行到第23行,调用了三次A类的构造函数没啥问题,因为new了三次A对象,分别给这三个A对象里的成员变量_a初始化为1、2、3,咱接着往下走
sp1拷贝构造sp4没啥问题;继续走
问题来了,当sp4赋值给sp2的时候怎么会调用了一次A类对象的析构?既然智能指针三大特性之一像指针一样使用,那我们可否这样理解:原本sp2是指向一块new出来的A类对象的空间且这个对象的成员变量_a初始化为2。当sp4赋值给sp2时,也就是sp2指向sp4所指向的内容,这时候就对sp2原本所指向的那块空间资源(即成员变量为2的A类对象)进行了释放,所以会调用它的析构,这就解释得通了。接着往下走
问题又来了,为什么这里sp3赋值给sp1 的时候没有调用A类对象的析构呢??我们画个图来分析:
所以我们得出一个结论:当智能指针指向另一块资源时,它原本所指向的资源如果没有被其它智能指针所指向那么这块资源就会被释放掉!!
换个说法:当一块资源没有智能指针管理的时候它就会被释放掉!!!
继续往后走:
结果就符合我们的推测了:sp2指向A(1),sp1指向A(3),对sp2所管理的对象里的成员变量++打印出来结果为2,对sp1所管理的对象的成员变量++打印出来的结果为4,正确!!