jake1036

面试100 30异常安全的复制

       面试100 30异常安全的赋值运算符重载函数

    当赋值运算符重载函数中有指针变量的时候,需要保证在发生异常的时候,对象的原有状态不发生改变。
   
   考虑下面的 未注意的代码
  

#include <iostream>
 
using namespace std ;
 
class MyString
 
{
    
public :
       MyString() ;
       MyString(
const MyString & rfs) ;           
       MyString 
& operator = (const MyString & rfs) ;
       
~MyString() ;
 
    
private :
    
char * data ;
       
 }
 ;
 
 MyString 
& MyString::operator = (const MyString & rfs) //普通的赋值操作符重载函数 
 {
   
if(this == &rfs)
     
return *this;
   
//接下来判断原来对象的heap成员是否已经删除,若未删除,则首先执行删除操作  
    if(data)
      
{
        delete [] data ;
        data 
= 0 ;
              
      }

      data 
= new char[strlen(rfs.data) + 1] ; //这可能会导致申请内存失败,造成原有对象状态被更改并无法回复 
      strcpy(data , rfs.data) ;
      
return *this ;      
            
 }


   上面申请内存空间的时候,可能会发生异常,但此时原有的内存空间已经释放,这样的话对象的状态被改变了。

  解决1 :

    考虑在分配内存空间的时候,先用一个辅助指针,指向新申请的内存空间,等申请成功的时候,再将原有对象的指针空间删除,
   将对象指针指向临时指针指向的空间。
  代码如下:
   

 //方法1 先在内存申请一块临时变量,申请成功的话,才会将this指针指向的原内存删除,将临时指针赋予 
  MyString & MyString::operator = (const MyString & rfs) //普通的赋值操作符重载函数 
 {
   
if(this == &rfs)
      
return *this;
    
char * temp = new char[strlen(rfs.data) + 1] ; //首先申请一块临时内存,以防止申请失败 
    strcpy(temp , rfs.data) ;
   
//只有上述内存申请成功,才进行删除原有的占用空间  
    if(data)
      
{
        delete [] data ;
        data 
= 0 ;
              
      }
    
      
this->data = temp ; //指向临时申请内存 
      return *this ;                
 }



方法2 :
   使用copy构造函数,建立一个临时对象,建立成功之后,将临时对象的指针与原对象交换。
  代码如下:
  

 //方法2.优雅的方法,在栈中使用copy构造函数,建立一个临时变量,建立成功之后。才执行内存中指针变量的复制 
  MyString & MyString::operator = (const MyString & rfs) //普通的赋值操作符重载函数 
 {
   
if(this == &rfs)
      
return *this;
    MyString tempStr(rfs.str) ;
    
char * temp = tempStr.data ; //使用copy构造函数,在栈中申明变量 
    tempStr.data = this->data ;  //交换两者的成员变量 
    this->data = temp ;          //结束的时候,tempStr会自动调用析构函数,将资源释放 
    return *this ;      
            
 }








 

posted on 2011-05-20 14:31 kahn 阅读(158) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理