16.4.2 关于auto_ptr的若干问题
auto_ptr不是万金油,在使用这种“智能指针”时需要特别注意以下问题。
1.auto_ptr只能用于堆内存的管理
auto_ptr类中使用delete释放其管理的内存区域,这就要求只能用堆内存(也就是new申请的内存)来初始化auto_ptr对象,下述用法显然是不合法的。
string sz("Hello,C++"); auto_ptr<string>ap(&sz);
2.auto_ptr对象赋值
如下代码所示。
auto_ptr<string>ap1(new string("Hello")); auto_ptr<string>ap2=ap1;
显然如果仅仅是指针赋值(浅复制),ap1和ap2维护的是同一块动态内存,当ap1和ap2都过期时,会试图删除同一块内存两次,这会引发错误。
为解决这个问题,auto_ptr类模板采用了“所有权”的概念,对同一块堆内存(即同一个对象),只能有一个auto_ptr对象拥有它,赋值操作会转移所有权,如下例所示。
ap2=ap1;
执行该赋值操作后,ap1便不再维护原来的堆内存,而将维护权转让给了ap2,此时ap1的值为null。
3.auto_ptr不能直接用于管理动态数组
auto_ptr中使用的delete,而不是delete[],因此auto_ptr不能直接用于动态数组的申请,如果需要对动态数组使用auto_ptr智能指针,可对auto_ptr进行扩充,如下所示。
template<class T,int num> class auto_array_ptr { auto_ptr<T>ap[num]; //添加对[]操作符的重载 };