03智能指针之shared_ptr
在接口类中使用智能指针时,如果要通过智能智能输出在内动态申请的内存空间的引用。
类内不维护内存空间的引用,只能使用shared_ptr;类内维护了内存空间的引用,则可以使用weak_ptr。
#include <iostream>
#include <memory>
using namespace std;
struct MyStruct
{
MyStruct() :size(100), pData(nullptr)
{
cout << "MyStruct() this:"<< this << endl;
pData = new unsigned char[100];
}
~MyStruct()
{
cout << "~MyStruct()this:" << this << endl;
if (nullptr != pData)
{
delete[] pData;
}
}
private:
int size;
unsigned char* pData;
};
void printSharedPtrInfo(const string& pName, const shared_ptr<MyStruct>& sp)
{
cout << pName.c_str() <<"\tuse_count():" << sp.use_count() << "\t";
cout << sp.get() << endl;
}
void printWeakPtrInfo(const string& pName, const weak_ptr<MyStruct>& wp)
{
cout << pName.c_str() << "\tuse_count():" << wp.use_count() << "\t";
if (!wp.expired())
{
auto sp = wp.lock();
cout << sp.get() << endl;
}
else
{
cout << "wp is nullptr" << endl;
}
}
void foo(const shared_ptr<MyStruct> sp)
{
cout << "enter the function foo()" << endl;
printSharedPtrInfo("sp",sp);
}
int main()
{
shared_ptr<MyStruct> sp = make_shared<MyStruct>();
printSharedPtrInfo("sp", sp);、
//正确——切记,shared_ptr赋值给weak_ptr时不能进行隐式类型转换
weak_ptr<MyStruct> wp = sp;
printWeakPtrInfo("wp", wp);
{
auto p1 = wp;
printWeakPtrInfo("p1", p1);
}
//这样的话,wp1右侧的shared_ptr被类型转换成weak_ptr,所以wp1引用计数为0
weak_ptr<MyStruct> wp1 = make_shared<MyStruct>();
printWeakPtrInfo("wp1", wp1);
{
auto p1 = wp1;
printWeakPtrInfo("p1", p1);
}
return 0;
//1.智能指针计数器递增
cout << "test use_count increasing........................." << endl;
//1.1.第一次将构造的对象赋值给sp,此时sp的引用计数为1
auto sp = make_shared<MyStruct>();
printSharedPtrInfo("sp",sp); //use_count(): 1
//1.2.进行一次赋值,引用计数+1,此时sp的引用计数为2
auto sp1 = sp;
printSharedPtrInfo("sp", sp); //use_count(): 2
//1.3.sp1与sp指向同一块内存,所以引用计数相同
printSharedPtrInfo("sp2", sp1); //use_count(): 2
//1.4.进行一次拷贝构造,引用计数+1,此时sp的引用计数为3
auto sp2(sp);
printSharedPtrInfo("sp", sp); //use_count(): 3
printSharedPtrInfo("sp1", sp1); //use_count(): 3
printSharedPtrInfo("sp2", sp2); //use_count(): 3
//1.5.作为参数传递给一个函数,引用计数+1,此时函数内部引用计数为4
foo(sp); //use_count(): 4
//1.6.离开函数作用域,函数内部局部对象被销毁,引用计数-1,此时引用计数为3
printSharedPtrInfo("sp1", sp1); //use_count(): 3
//2.智能指针计数器递减
cout << "test use_count reducing........................." << endl;
//2.1.第一次将构造的对象赋值给sp,引用计数为1
auto spp = make_shared<MyStruct>();
//2.2.进行一次赋值,引用计数+1
auto spp1 = spp;
printSharedPtrInfo("spp", spp); //2
{
//2.2大括号作用域内,spp赋值给sp2,引用计数+1,此时spp的引用计数为2
auto sp2 = spp;
printSharedPtrInfo("spp", spp); //3
}
//2.3.离开大括号作用域内,引用计数-1, 此时spp的引用计数为1
printSharedPtrInfo("spp", spp); //2
//2.4.智能指针调用 reset,清零引用计数,并释放资源
cout << "test reset()........................." << endl;
spp.reset();
printSharedPtrInfo("spp", spp); //0
printSharedPtrInfo("sp", sp); //3
//2.5.将一个应用计数为0的智能指针赋值给sp,则sp也清零引用计数,并释放资源
sp = spp;
printSharedPtrInfo("sp", sp); //0
printSharedPtrInfo("spp", spp); //0
}
道虽迩,不行不至;事虽小,不为不成。