zoukankan      html  css  js  c++  java
  • C++ Primer 有感(异常处理)(三)

    先看下面的代码:

    1. int main()  
    2. {     
    3.     int *i=new int(10);  
    4.     /* 
    5.         这中间的代码出现异常 
    6.     */  
    7.   
    8.     delete i;  
    9.   
    10.     return 0;  
    11. }  

     

    如果出现了这样的情况,动态分配的内存就不会被释放。为了处理这样的问题,可以使用C++标准库auto_ptr类。

    如果使用下面的代码,内存就一定会被释放

    1. #include<memory>  
    2. int main()  
    3. {     
    4.     std::auto_ptr<int> ptr(new int(10));  
    5.     /* 
    6.         这中间的代码出现异常 
    7.     */  
    8.   
    9.     return 0;  
    10. }  


    auto_ptr类是接受一个类型形参的模板,它为动态分配的对象提供异常安全。auto_ptr类在头文件memory中定义。

    1. auto_ptr<T> ap    创建名为ap的未绑定的auto_ptr对象  
    2. auto_ptr<T> ap(p) 创建名为ap的auto_ptr对象,ap拥有指针p指向的对象。该构造函数为explicit  
    3. auto_ptr<T> ap1(ap2) 创建名为ap1的auto_ptr对象,ap1保存原来存储在ap2中的指针。ap2将所有权转给ap1,ap2成为未绑定的auto_ptr对象。  
    4. ap1=ap2           将所有权转给ap1.删除ap1指向的对象,并使ap1指向ap2指向的对象,使ap2成为未绑定的  
    5. *ap               返回ap绑定对象的引用  
    6. ap->              返回ap保存的指针  
    7. ap.reset(p)       如果p与ap的值不同,则删除ap指向的对象并且将ap绑定到p  
    8. ap.release()      返回ap保存的指针并且使ap成为未绑定的  
    9. ap.get()          返回ap保存的指针  

     

    auto_ptr只能用于管理从new返回的一个对象,它不能管理动态分配的数组。auto_ptr对象在复制和赋值的时候有不同寻常的行为,所以不能将auto_ptr存放到保准库容器类型中。

    当auto_ptr对象超出作用域或者被撤销的时候,就会自动释放aotu_ptr保存指针指向对象的内存。

     

    auto_ptr是可以保存任何类型指针的模板

     

    初始化auto_ptr对象的时候,使用如下方法

    auto_ptr<int> i(new int(10));

    如下初始化是错误的:

    auto_ptr<int> i=new int(10);

     

    i所指的由new表达式创建的对象在超出作用域时自动删除。如果i是局部对象,i所指对象在定义i的块的末尾删除;如果发生异常,则i也超出作用域,析构函数将自动运行i的析构函数作为异常处理的一部分;如果i是全局对象,就在程序末尾删除i引用的对象。

    如下代码:

    auto_ptr<string> ptr(new string("HELLO"));

    *ptr="HELLO";   //改变ptr所保存的指针所指对象的内容

    string s=*ptr;     //返回ptr所保存指针所指对象

    if(ptr->empty())  //判断ptr所指对象是否为空

    1. #include<memory>  
    2. #include<iostream>  
    3. #include<string>  
    4. using namespace std;  
    5. int main()  
    6. {     
    7.     std::auto_ptr<string> ptr(new string("HELLO"));  
    8.       
    9.     /* 
    10.         这中间的代码出现异常,内存照样回收 
    11.     */  
    12.     cout<<*ptr<<endl;  
    13.     string s=*ptr;  
    14.     *ptr="zhycheng";  
    15.     cout<<*ptr<<endl<<(ptr->empty())<<endl;  
    16.   
    17.   
    18.   
    19.     /* 
    20.         这中间的代码出现异常,内存照样回收 
    21.     */  
    22.       
    23.     return 0;  
    24. }  


    复制auto_ptr对象的时候,如下

    auto_ptr<int> ap1(ap2);

    那么ap1将获得ap2所保存指针的管理,ap2将会变为未绑定

    如果是赋值的话

    ap3=pa2;

    将删除ap3保存的指针所指对象

    ap3置为ap2所指对象

    ap2未绑定

     

     

    如果不给定初始化式,ptr的值为0,对0指针解引用,程序出错并且没有定义会发生什么事。使用VC++的编译器的情况是程序崩溃。

    可以使用ptr.get()获得ptr保存的指针来判断ptr是否绑定。

    auto_ptr的reset函数接受一个指针,来改变auto_ptr保存的指针,如果新指针与旧指针不同,则删除旧指针所指对象的空间。相同的话就没什么改变。

     

    auto_ptr要注意如下四点:

    1.不要使用auto_ptr对象保存指向静态分配内存对象的指针

    2.不要使用两个auto_ptr对象保存同一指针

    3.不要使用auto_ptr保存动态分配数组的指针

    4.不要将auto_ptr对象存储在容器中

  • 相关阅读:
    E
    CSU 1757 火车进站 1757
    [Unity游戏开发]场景切换
    相机跟随
    [Unity游戏开发]Vector3类
    [Unity游戏开发] 关于向量计算的一些基础
    [Unity游戏开发] MonoBehaviour类常用方法(脚本生命周期)
    C#学习笔记之——new在哪些地方用
    C#——快速排序
    C#学习笔记之——事件(Event)
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6332721.html
Copyright © 2011-2022 走看看