shared_ptr和new结合使用
我们除了使用make_shared来初始化一个智能指针,还可以使用new返回的指针来初始化智能指针。
shared_ptr<int> p1(new int(42));//p1指向一个值为42的int
shared_ptr<int> p2 = new int(1024);//错误,不能将一个内置指针隐式转化为智能指针。
我们不能将一个内置指针隐式转化为智能指针。
shared_ptr<int> clone(int p){
return new int(p);//错误,不能隐式转化
}
shared_ptr<int> clone(int p){
return shared_ptr<int>(new int(p));//正确
}
不要混合使用普通指针和智能指针!
void process(shared_ptr<int> ptr){
//使用ptr
}//离开作用域,ptr被销毁
例如,下面这段代码就是正确的:
shared_ptr<int> p(new int(42));//p的引用计数为1
process(p);//拷贝p,增加的p的引用计数,这时p的引用计数为2
int i = *p;//此时,离开process作用域,p的引用计数减1,变为1,
下面这段代码就有错误:
int *x(new int(24));//x是一个普通指针,不是智能指针
process(x);//错误,不能将int*转化为一个shared_ptr
process(shared_ptr<int>(x));//合法的,但是离开process作用域的时候,这个智能指针指向的内存会被释放
int j = *x;//未定义的,因为x是个空悬指针,内存已经被释放了
不要使用get初始化另一个智能指针或者为智能指针赋值
有时候,我们需要向不能使用智能指针的代码传递一个内置指针。智能指针类型定义了一个名为get的函数,它返回一个内置指针 指向智能指针所管理的对象。
shared_ptr<int> p(new int(42));
int *q = p.get();//返回了一个内置指针,但是使用q的时候要注意,不要让它管理的内存释放
{
shared_ptr<int>(q);
}//程序块结束,q被销毁,它指向的内存被释放
int foo = *p;//未定义,p指向的内存已经被释放了
reset操作
shared_ptr<int> p (new int(1024));//
p.reset(new string("hello));//p指向一个新的对象
reset一般会和unique一起使用,来控制多个shared_ptr共享的对象。
shared_ptr<int> p(new int(42));
if (!p.unique()){
p.reset(new string("hello"));//我们不是唯一用户,分配新的拷贝
}
*p += newVal;//现在我们知道我们是唯一的用户,可以改变对象的值