每个auto_ptr对象绑定到一个对象或者指向一个对象。当auto_ptr对象指向一个对象的时候,可以说它“拥有”该对象。当auto_ptr对象超出作用域或者另外撤销的时候,就自动回收auto_ptr所指向的动态分配对象。
(3)内存分配中使用auto_ptr
如果通过常规指针分配内存,而且在执行delete之前发生异常,就不会自动释放内存,
1: void f() 2: { 3: int *ip = ne int(42); //dynamically allocate a new object 4: //code that throws an exception that is not caugth inside f 5: delete ip; //return the memory before exiting 6: }
如果在new和delet之间发生异常,并且该异常不被局部捕获,就不会执行delet,永远也收不回该内存,若使用auto_ptr对象来替代,将会自动释放内存,即使提早退出这个块,
1: void f() 2: { 3: auto_ptr
这个例子中,编译器保证在展开栈越过f之前运行ap的析构函数。
(4)auto_ptr是可以保存任何类型指针的模板
auto_ptr类是接收单个类型形参的模板,该类型指定auto_ptr可以绑定的对象类型,因此,可以创建任何类型的auto_ptr:
1: auto_ptr
(5)将auto_ptr绑定到指针
在最常见的情况下,将auto_ptr对象初始化为由new表达式返回的对象的地址:
1: auto_ptr
注意,接受指针的构造函数为explicit构造函数,所以必须用初始化的直接形式来创建auto_ptr对象。
1: auto_ptr
pi所指的由new表达式创建的对象在超出作用域时自动删除。
(6)使用auto_ptr对象
1: auto_ptr
auto_ptr的主要目的是在保证自动删除auto_ptr对象引用的对象的同时,支持普通指针式行为。
(7)auto_ptr对象的赋值和复制是破坏性操作
auto_ptr与普通指针的复制和赋值有区别。普通指针赋值或复制后两个指针指向同一对象,而auto_ptr对象复制或赋值后,将基础对象的所有权从原来的auto_ptr对象转给副本,原来的auto_ptr对象重置成为未绑定状态。
1: auto_ptr
auto_ptr的复制和赋值改变右操作数,因此,auto_ptr赋值的左右操作数必须是可修改的左值。auto_ptr不能存储在标准容器中,因为标准库容器要求在复制或赋值后两对象相等,auto_ptr不满足 条件,如果将ap2赋值给ap1,则在赋值后ap1!=ap2,复制也类似。
(8)赋值删除左操作数指向的对象
除了将所有权从右操作数转给左操作数外,赋值还删除左操作数原来指向的对象--假如两个对象不同,通常自身赋值没有效果。
1: auto_ptr
将ap2赋值给ap3后,1)删除了ap3指向的对象;2)将ap3置为指向ap2指向的对象;3)ap2是未绑定的auto_ptr对象
(9)auto_ptr的默认构造函数
如果不给定初始式,auto_ptr对象是未绑定的,它不指向任何对象,默认情况下,auto_ptr的内部指针值置为0。
(10)测试auto_ptr对象
例子中第一种条件测试是错误的, auto_ptr 类型没有定义到可用作条件的类型的转换,相反,要测试auto_ptr 对象,必须使用它的 get 成员,该成员返回包含在 auto_ptr 对象中的基础指针。
示例:
1: // error: cannot use an auto_ptr as a condition 2: if (p_auto) 3: *p_auto = 1024; 4: 5: // revised test to guarantee p_auto refers to an object 6: if (p_auto.get()) 7: *p_auto = 1024;
应该只用 get 询问 auto_ptr 对象或者使用返回的指针值,不能用 get 作为创建其他 auto_ptr 对象的实参。(原因:使用get成员初始化其他auto_ptr对象,违反了auto_ptr类的设计原则,在任意时刻只有一个auto_ptr对象保存给定指针,如果两个auto_ptr对象保存相同指针,则该指针会被delete两次!!!)
(11)reset操作
auto_ptr对象与内置指针的另一个区别是不能直接将一个地址(或其它指针)赋给auto_ptr对象。
1: #include