重载赋值运算符的策略

重载赋值运算符的策略
赋值运算符的重载,有不同的方法,Effective C++ 中有一个条款对此介绍。
 1  #include  < iostream >
 2  using   namespace  std;
 3 
 4  class  MyString
 5  {
 6  private :
 7      unsigned len;
 8       char *  data;
 9  public :
10      MyString( const   char *  s  =   "" );
11      MyString( const  MyString &  s);
12      MyString &   operator   =  ( const  MyString &  s);
13       ~ MyString();
14  };
15 
16  MyString::MyString( const   char *  s)
17  {
18      len  =  strlen(s);
19      data  =   new   char [len  +   1 ];
20       if  (data  !=   0 )
21      {
22          strcpy(data, s);
23      }
24  }
25 
26  MyString::MyString( const  MyString &  s)
27  {
28      len  =  s.len;
29      data  =   new   char [len  +   1 ];
30       if  (data  !=   0 )
31      {
32          strcpy(data, s.data);
33      }
34  }
35 
36  MyString &  MyString::  operator   =  ( const  MyString &  s)
37  {
38       //  第一种方法,需要检测自赋值,因为如果不检测,则会造成当自赋值时,就直接将该对象的 data delete 了,也就是 s.data 被 delete 了。这时 s.data 是个悬置指针,所致内存极可能无效
39       //
40       // if (this != &s)
41       // {
42       //     delete [] data;
43       //     len = s.len;
44       //     data = new char[len + 1];
45       //     if (data != 0)
46       //     {
47       //         strcpy(data, s.data);
48       //     }
49       // }
50       // return *this;
51      
52       //  另一种方法, 不需要检测自赋值
53       //  这种方式需要做一个备份,自赋值情况下,temp 保持了另一份备份,即便 delete 了 data 还是留有一份
54       //  非自赋值的情况下,对 s.data 所指的内容有了一个备份,然后 delete data,将 temp 赋予 data,这样有了两份 s.data,到达赋值的目的
55      len  =  s.len;
56       char *  temp  =   new   char [len  +   1 ];
57       if  (temp  !=   0 )
58      {
59          strcpy(temp, s.data);
60      }
61      delete [] data;
62      data  =  temp;
63       return   * this ;
64 
65       //  两种方法的代价分析
66       //  第一种方法,需要每次都要检测是不是自赋值了,对于自赋值的情况,虽然检测了,但是避免了备份,有利于自赋值的情况。但是对于非自赋值的情况,都需要额外的检测,这种检测是浪费的
67       //  第二种方法,不管是自赋值还是非自赋值都需要备份,这种方法对于自赋值的情况,较第一种方法代价高些,但是对于非自赋值的情况它不需要检测,也是做一个 copy 所以非自赋值的情况效率由于第一种方法
68       //  也就是说第一种方法对于自赋值的情况好,第二种方法对于非自赋值的情况好。一般情况下,自赋值的情况并不经常出现,所以第一种检测自赋值的操作很多情况下是多余的,所以相对第一种方法,第二种方法更好些。
69  }
70 
71  MyString:: ~ MyString()
72  {
73      len  =   0 ;
74      delete [] data;
75  }
76 
77  int  main()
78  {
79      MyString a( " C++ Programming " ), c( " Hello " );
80      MyString b(a);
81      c  =  b;
82      cout  <<   " . . . "   <<  endl;
83       return   0 ;
84  }


你可能感兴趣的:(重载赋值运算符的策略)