本文共 1958 字,大约阅读时间需要 6 分钟。
shared_ptr和new的结合使用
如果我们不初始化一个智能指针,它就会被初始化为一个空指针,我们可以用new返回的指针来初始化智能指针 接受指针参数的智能指针构造函数是explicit的。因此,我们不能将一个内置指针隐式转化为一个智能指针,必须使用直接初始化形式来初始化为一个智能指针shared_ptr p1 = new int(1024); //错误:必须使用直接初始化形式shared_ptr p2(new int(1024)); //正确,使用了直接初始化形式
p1的初始化隐式地要求用一个new返回的int*来创建一个shared_ptr。由于我们不能进行内置指针到智能指针的隐式转化,因此这条初始化语句是错误的。由于相同的原因,一个返回shared_ptr的函数不能在其返回语句中隐式转化一个普通的指针:
shared_ptr clone(int p){ return new int(p); //错误:试图隐式转化为shared_ptr }
我们必须将shared_ptr显式地绑定到一个想要返回的指针上:
shared_ptr clone(int p){ //显式用int*创建shared_ptr return shared_ptr (new int(p));}
定义和改变shared_ptr的其他方法
shared_ptrp(q); //p管理内置指针q所指的对象;q必须指向new分配的内存,且能够转化为T*类型shared_ptr p(u); //p从unique_ptr u那里接管了对象的所有权,将u置空shared_ptr p(q, d); //p将使用可调用对象d来代替deletep.reset(); //若p是唯一指向其对象的shared_ptr,reset会释放此对象p.reset(q); //若传递了可选的参数内置指针q,会令p指向q,否则会将p置空p.reset(q, d);
不要混合使用普通指针和智能指针
void process(shared_ptr ptr){ //使用ptr} //ptr离开作用域被销毁
int *x(new int(1024)); //危险:x是一个普通指针,而不是一个智能指针process(x); //错误:不能将int*转化为一个shared_ptr process(shared_ptr (x)); //合法:但内存会被释放int j = *x; //未定义的,x为一个空悬指针
上面的调用中,我们将一个临时shared_ptr传递给process。当这个调用表达式结束时,这个临时对象也就被销毁了。引用计数递减为0,所指向的内存会被释放。
shared_ptr x(new int(1024));process(x); //拷贝x会递增它的引用计数,在process中引用计数值为2int j = *x; //正确:引用计数值为1
使用一个内置指针来访问一个智能指针所负责的对象是很危险的,因为我们无法知道对象何时会被销毁。
不要使用get初始化另一个智能指针或为智能指针赋值
智能指针定义了一个名为get的函数,它返回一个内置指针,指向智能指针管理的对象。此函数为下面一种情况所设计的:我们需要向不能使用智能指针的代码传递一个内置指针。使用get返回的指针的代码不能delete此指针。shared_ptr p(new int(42)); //引用计数为1int *q = p.get(); //正确,但不要让q所管理的内存释放{ //新的程序块 //未定义:两个独立的shared_ptr指向相同的内存 shared_ptr (q);} //程序块结束,q被销毁,它指向的内存被释放int foo = *p; //未定义:P指向的内存被释放了
当我们使用p时会发生未定义的行为,而且当p销毁时,这块内存会被第二次delete
get用来将指针的访问权限传递给代码,你只有在确定不会delete指针的情况下,才能使用get。特别是,永远不要get初始化另一个智能指针或者为另一个指针指针赋值。转载地址:http://btxmb.baihongyu.com/