由于用muduo库,所以对shared_ptr有一定的了解;但是,对于unique_ptr就有些茫然了于是,了解了些相关资料,并且写了测试代码,对其有了一定的了解。
首先说明下,每一个pointer,都指向一个obj;每一个pointer,对该obj持有;
一、unique_ptr
unique_ptr,其实就是一个简单的指针,它实现的功能,仅仅就是在作用域内有效,超过作用域就会自动释放。
在这个生命周期以内,可以转交给其它unique_ptr,但是,自己就放弃了对其的持有.
下面,3个测试:
1、test_move是通过move将p1的持有权交给了p0;(这个我不是很理解)
2、test_get,get函数仅仅返回原生指针,p0通过reset构造了自己;那么,两个指针都对对象有持有权,函数结束导致两个都会释放,core。
3、test_release,p1通过release自己释放了持有权,转交给了p0;
二、shared_ptr
1、test_shared_ptr1,测试operator=赋值,引用计数加1(use_count=2);释放一次;
2、test_shared_ptr2,测试get+reset,发现引用计数为1,析构函数也调用了两次。
首先说明下,每一个pointer,都指向一个obj;每一个pointer,对该obj持有;
一、unique_ptr
unique_ptr,其实就是一个简单的指针,它实现的功能,仅仅就是在作用域内有效,超过作用域就会自动释放。
在这个生命周期以内,可以转交给其它unique_ptr,但是,自己就放弃了对其的持有.
下面,3个测试:
1、test_move是通过move将p1的持有权交给了p0;(这个我不是很理解)
2、test_get,get函数仅仅返回原生指针,p0通过reset构造了自己;那么,两个指针都对对象有持有权,函数结束导致两个都会释放,core。
3、test_release,p1通过release自己释放了持有权,转交给了p0;
二、shared_ptr
1、test_shared_ptr1,测试operator=赋值,引用计数加1(use_count=2);释放一次;
2、test_shared_ptr2,测试get+reset,发现引用计数为1,析构函数也调用了两次。
注意:不要用get函数获取原生指针之后,对智能指针进行赋值;因为,get获取到的原生指针没有智能指针的信息,导致智能指针无法进行管理对象。切记切记
#include <memory>
#include <cstdio>
using std::unique_ptr;
using std::shared_ptr;
struct T
{
T(){printf("-- run here 1:%p!\n",this);}
T(const T&){printf("-- run here 2:%p!\n",this);}
const T& operator=(const T&){printf("-- run here 3:%p!\n",this);return *this;}
~T(){printf("-- end here 1:%p!\n",this);}
long l;
};
#define CHECKPOINT(p0,p1) \
do\
{\
printf("\t%s is %p;\n",#p0,p0.get());\
printf("\t%s is %p;\n",#p1,p1.get());\
}while(0)
void test_move()
{
unique_ptr<T> p0;
unique_ptr<T> p1(new T);
//p0 = p1; //error;
p0 = std::move(p1);
CHECKPOINT(p0,p1);//p1=NULL;p0指向对象;
}
void test_get()
{
unique_ptr<T> p0;
unique_ptr<T> p1(new T);
//Notice that a call to this function does not make unique_ptr release ownership of the pointer .
//Therefore, the value returned by this function shall not be used to construct a new managed pointer.
//p1仍然对T对象持有,所以,CHECKPOINT发现p0,p1都指向同一个地方;所以,函数执行结束会挂B(free two times).
p0.reset(p1.get());
CHECKPOINT(p0,p1);
}
void test_release()
{
unique_ptr<T> p0;
unique_ptr<T> p1(new T);
p0.reset(p1.release());
CHECKPOINT(p0,p1);//p1=NULL;p0指向对象;
}
void test_unique_ptr()
{
printf("--------------test_unique_ptr---------------\n");
printf("test move:\n");
test_move();
//printf("test get:\n");
//test_get();
printf("test release:\n");
test_release();
}
//---------------------------------------------------------------------------------------
void test_shared_ptr1()
{
shared_ptr<T> p0;
shared_ptr<T> p1(new T);
p0=p1;
printf("\ttest_=:p0.use_count()=%ld;p1.use_count()=%ld;\n",p0.use_count(),p1.use_count());
CHECKPOINT(p0,p1);
}
//引用计数为1,两个指针指向的对象也是相同;而且会调用两次析构函数(p0,p1析构的时候分别调用一次);
void test_shared_ptr2()
{
shared_ptr<T> p0;
shared_ptr<T> p1(new T);
p0.reset(p1.get());
//p0.reset(p1);//error;
printf("\ttest_reset-get:p0.use_count()=%ld;p1.use_count()=%ld;\n",p0.use_count(),p1.use_count());
CHECKPOINT(p0,p1);
}
void test_shared_ptr()
{
printf("--------------test_shared_ptr---------------\n");
test_shared_ptr1();
test_shared_ptr2();
}
int main()
{
//test_unique_ptr();
test_shared_ptr();
return 0;
}