当前位置:编程学习 > C/C++ >>

第17章 用于大型程序的工具(5)

上一篇:http://www.zzzyk.com/kf/201112/115672.html

17.1.9 auto_ptr类

auto_ptr类在头文件memory中定义。

auto_ptr只能用于管理从new返回的一个对象,它不能管理动态分配的数组。

正如我们所见,当auto_ptr被复制或赋值的时候,有不同寻常的行为,因此,不能将auto_ptr存储在标准库容器类型中。

每个auto_ptr对象绑定到一个对象或者指向一个对象。当auto_ptr对象指向一个对象的时候,可以说它“拥有”该对象。当auto_ptr对象超出作用域或者另外撤销的时候,就自动回收auto_ptr所指向的动态内存对象。

1. 为异常安全的内存分配使用auto_ptr

auto_ptr<int> i(new int(42)); //auto_ptr manage int* i...  
throw exception(); 
 auto_ptr<int> i(new int(42)); //auto_ptr manage int* i...
 throw exception();2. auto_ptr是可以保存任何类型指针的模板

auto_ptr类是接受某个单个类型形参的模板,该类型指定auto_ptr可以绑定的对象的类型,因此,可以创建任何类型的auto_ptr。

3. 将auto_ptr绑定到指针

接受指针的构造函数为explicit构造函数,所以必须使用初始化的直接形式来创建auto_ptr对象。

4. 使用auto_ptr对象

auto_ptr<string> i(new string("42")); //auto_ptr manage string* i...  
//throw exception();  
cout<<*i<<endl; 
cout<<i->length()<<endl; 
 auto_ptr<string> i(new string("42")); //auto_ptr manage string* i...
 //throw exception();
 cout<<*i<<endl;
 cout<<i->length()<<endl;auto_ptr的主要目的是,在保证自动删除auto_ptr对象引用的对象的同时,支持普通指针式行为。正如我们所见,自动删除该对象这一事实导致在怎样复制和访问它们的地址值方面,auto_ptr与普通指针明显不同。

5. auto_ptr对象的复制和赋值是破坏性操作

auto_ptr和内置指针对待复制和赋值有非常关键的重要区别。当复制auto_ptr对象或者将它的值赋给其他auto_ptr对象的时候,将基础对象的所有权从原来的auto_ptr对象转给副本,原来的auto_ptr对象重置为未绑定状态。

与其他复制或赋值操作不同,auto_ptr的复制和赋值改变右操作数,因此,赋值的左右操作数必须都是可修改的左值。

6. 赋值删除左操作数指向的对象

除了将所有权从右操作数转给左操作数之外,赋值还删除左操作数原来指向的对象——假如两个对象不同。通常自身赋值没有效果。

因为复制和赋值时破坏性操作,所以不能将auto_ptr对象存储在标准容器中。标准库的容器类要求复制或赋值之后两个对象相等,auto_ptr不满足这一要求。

7. auto_ptr的默认构造函数

如果不给顶初始式,auto_ptr对象是未绑定的,它不指向对象。

默认情况下,auto_ptr的内部指针值置为0。对未绑定的auto_ptr对象解引用,其效果与对未绑定的指针解引用相同——程序出错而且没有定义会发生什么。

8. 测试auto_ptr对象

为了检查指着是否未绑定,可以在条件中直接测试指针,效果是确定指针是否为0.相反,不能直接测试auto_ptr对象。

auto_ptr类型没有定义到可用作条件的类型的转换,相反,要测试auto_ptr对象,必须使用它的get成员,该成员包含在auto_ptr对象中的基础指针。

auto_ptr<string> i(new string("42")); //auto_ptr manage string* i...  
//throw exception();  
if(i.get()){ 
    cout<<*i<<endl; 
    cout<<i->length()<<endl; 

 auto_ptr<string> i(new string("42")); //auto_ptr manage string* i...
 //throw exception();
 if(i.get()){
  cout<<*i<<endl;
  cout<<i->length()<<endl;
 }为了确定auto_ptr是否指向一个对象,可以将get的返回值与0比较。

应该只用get询问auto_ptr对象或者使用返回的指针值,不能用get作为创建其他auto_ptr对象的实参。

使用get成员初始化其他auto_ptr对象违反auto_ptr类设计原则:在任意时刻只有一个auto_ptr对象保存给定指针,如果两个auto_ptr对象保存相同的指针,该指针就会被delete两次。

9. reset操作

auto_ptr对象与内置指针的另一个区别是,不能直接将一个地址(或者其他指针)赋给auto_ptr对象,相反,必须调用reset函数来改变指针。

调用auto_ptr函数对象的reset函数时,在将auto_ptr对象绑定到其他对象之前,会删除auto_ptr对象所指向的对象(如果存在)。但是,正如自身赋值是没有效果的一样,如果调用该auto_ptr对象已经保存的同一指针的reset函数,也没有效果,不会删除对象。

auto_ptr<string> i(new string("42")); //auto_ptr manage string* i...  
//throw exception();  
if(i.get()){ 
    i.reset(new string("Anders")); 
    cout<<*i<<endl;   //Anders  
    cout<<i->length()<<endl; //6  

 摘自 xufei96的专栏
 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,