关于智能指针的注意项

1.std::auto_ptr

智能指针本身就是一个对象,要检查其包含的裸指针 是否存在要用对象.get()方法

(1)使用重载过的 “=” 将一个原有auto_ptr对象赋值给新创建的对象,实质上新对象夺取了原有对象的内存管理权,原有对象就悬空了;再调用方法就会崩溃;
(2)要是使用拷贝构造,实际上只有一块内存,这时内存所有者成为了新对象,新对象出了其函数作用域就会自动析构,释放掉这片内存,旧对象使用方法就会报错崩溃
(3).release()方法只是让出了内存的所有权,而不是释放掉了

std::auto_ptr 可用来管理单个对象的对内存,但是,请注意如下几点

1)    尽量不要使用“operator=”以及拷贝构造。如果使用了,请不要再使用先前对象。

(2)    记住 release() 函数不会释放对象,仅仅归还所有权。

(3std::auto_ptr 最好不要当成参数传递(因为出了函数作用域,空间就会销毁,实参就成为野指针)。

(4)    由于 std::auto_ptr 的“operator=”问题,有其管理的对象不能放入 std::vector 等容器中。

2.shared_ptr
专门用于共享所有权的,由于要共享所有权,其在内部使用了引用计数

多个指针可以指向一个对象,当最后一个指针退出时才会自动释放内存;

通过调用use_count()可以得到引用计数, 据此你能找到shared_ptr的数量,shared_ptr默认调用delete释放关联的资源。如果用户采用一个不一样的析构策略时,他可以自由指定构造这个shared_ptr的策略

void main( )
{
 shared_ptr<Test> sptr1( new Test[5], 
        [ ](Test* p) { delete[ ] p; } );
}
在此场景下,shared_ptr指向一组对象,但是当离开作用域时,
默认的析构函数调用delete释放资源。实际上,我们应该调用delete[]来销毁这个数组。
用户可以通过调用一个函数,例如一个lamda表达式,来指定一个通用的释放步骤。

(1)reset(): 释放关联内存块的所有权,如果是最后一个指向该资源的shared_ptr,就释放这块内存。
(2)unique: 判断是否是唯一指向当前内存的shared_ptr.
当两个不同组的shared_ptr<> 对象指向同一个对象,就会出现错误,尽量避免这种情况 ;

还有:循环引用.A对B有一个shared_ptr, B对A也有一个shared_ptr ,与sptrA和sptrB关联的资源都没有被释放(当B离开其作用域,其引用计数并没有完全释放,值到了1)

3.weak_ptr

为了解决上面循环引用的问题,引入此指针。
weak_ptr可以共享shared_ptr持有的资源。所以可以从一个包含资源的shared_ptr创建weak_ptr。
weak_ptr不支持普通指针包含的*,->操作。它并不包含资源所以也不允许程序员操作资源

从weak_ptr中创建shared_ptr然后再使用它。通过增加强引用计数,当使用时可以确保资源不会被销毁。当引用计数增加时,可以肯定的是从weak_ptr中创建的shared_ptr引用计数至少为1

创建

可以以shared_ptr作为参数构造weak_ptr.从shared_ptr创建一个weak_ptr增加了共享指针的弱引用计数(weak reference),意味着shared_ptr与其它的指针共享着它所拥有的资源。但是当shared_ptr离开作用域时,这个计数不作为是否释放资源的依据。换句话说,就是除非强引用计数变为0,才会释放掉指针指向的资源,在这里,弱引用计数(weak reference)不起作用。

void main( )
{
 shared_ptr<Test> sptr( new Test );
 weak_ptr<Test> wptr( sptr );
 weak_ptr<Test> wptr1 = wptr;
}
此时wptr1有两个弱引用,一个强引用计数。
将一个weak_ptr赋给另一个weak_ptr会增加弱引用计数(weak reference count)。

当shared_ptr离开作用域时,其内的资源释放了,这时候指向该shared_ptr的weak_ptr发生了什么?weak_ptr过期了(expired);
(1)判断weak_ptr是否指向有效资源,有两种方法:
调用use-count()去获取引用计数,该方法只返回强引用计数,并不返回弱引用计数。
调用expired()方法。比调用use_count()方法速度更快。

从weak_ptr调用lock()可以得到shared_ptr或者直接将weak_ptr转型为shared_ptr
void main( )
{
 shared_ptr<Test> sptr( new Test );
 weak_ptr<Test> wptr( sptr );
 shared_ptr<Test> sptr2 = wptr.lock( );
}

4.unique_ptr

遵循着独占语义。在任何时间点,资源只能唯一地被一个unique_ptr占有。当unique_ptr离开作用域,所包含的资源被释放。如果资源被其它资源重写了,之前拥有的资源将被释放。所以它保证了他所关联的资源总是能被释放。

unique_ptr提供了创建数组对象的特殊方法,当指针离开作用域时,调用delete[]代替delete

unique_ptr<int[ ]> uptr( new int[5] );

当把unique_ptr赋给另外一个对象时,资源的所有权就会被转移。

记住unique_ptr不提供复制语义(拷贝赋值和拷贝构造都不可以),只支持移动语义(move semantics).

unique_ptr提供一个release()的方法,释放所有权,但是不释放资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值