关于含有成员指针的类的复制控制

关于含有成员指针的类的复制控制

关于含有成员指针的类的复制控制

一个类中如果含有了指针成员,在不加任何措施的时候,复制类对象是做的位复制操作,即是所谓的浅拷贝,两个对象的指针式一样的值,指向同一块内存区。
这种情况下,当一个对象删除其成员指针指向的内存区后,另一个对象的指针成员指向的内存区也就被释放了。
如果第一个对象析构时删除了这个内存区,那么在第二对象析构时造成同一块内存多次被释放,程序崩溃。

解决这个问题有常规上有两种方法
一是,进行深拷贝,在拷贝构造函数和复制运算符中进行相应的内存分配和复制工作。析构的时候只是各自析构各自的。
二是,采用引用计数手段,在拷贝构造函数和复制运算符中对引用计数进行分析,多个复制对象的指针成员只指向同一个内存区,在最后一个对象析构的时候才最终将这个内存区释放掉。
引用计数的好处是,可以节省内存分配、拷贝、内存释放所带来的效率消耗,以及节省内存。

http://www.cppblog.com/jake1036/archive/2011/05/17/146594.html

浅拷贝

 1  #include  < iostream >
 2  #include  < cstring >
 3  using   namespace  std;
 4 
 5  class  str
 6  {
 7  private :
 8       char *  s_;
 9  public :
10      str( const   char *  s  =   "" )
11      {
12          s_  =   new   char [strlen(s)  +   1 ];
13           if  (s_  !=   0 )
14          {
15              strcpy(s_, s);
16          }
17      }
18       ~ str()
19      {
20          delete [] s_;
21      }
22       char *  s()  const
23      {
24           return  s_;
25      }
26  };
27 
28  ostream &   operator   <<  (ostream &   out const  str &  s)
29  {
30       out   <<  s.s()  <<  endl;
31       return   out ;
32  }
33 
34  int  main()
35  {
36      str s1  =   " 123 " ;
37      str s2(s1);
38      cout  <<  s1  <<  endl;
39      cout  <<  s2  <<  endl;
40  }

 


深拷贝
 1  #include  < iostream >
 2  #include  < cstring >
 3  using   namespace  std;
 4 
 5  class  str
 6  {
 7  private :
 8       char *  s_;
 9  public :
10      str( const   char *  s  =   "" )
11      {
12          s_  =   new   char [strlen(s)  +   1 ];
13           if  (s_  !=   0 )
14          {
15              strcpy(s_, s);
16          }
17      }
18      str( const  str &  s)
19      {
20          s_  =   new   char [strlen(s.s_)  +   1 ];
21           if  (s_  !=   0 )
22          {
23              strcpy(s_, s.s_);
24          }
25      }
26      str &   operator   =  ( const  str &  s)
27      {
28           if  ( this   !=   & s)
29          {
30              delete [] s_;
31              s_  =   new   char [strlen(s.s_)  +   1 ];
32               if  (s_  !=   0 )
33              {
34                  strcpy(s_, s.s_);
35              }
36          }
37           return   * this ;
38      }
39       ~ str()
40      {
41          delete [] s_;
42      }
43       char *  sr()  const
44      {
45           return  s_;
46      }
47  };
48 
49  ostream &   operator   <<  (ostream &   out const  str &  s)
50  {
51       out   <<  s.sr()  <<  endl;
52       return   out ;
53  }
54 
55  int  main()
56  {
57      str s1  =   " 123 " ;
58      str s2(s1);
59      cout  <<  s1  <<  endl;
60      cout  <<  s2  <<  endl;
61  }


引用计数
引用计数的实现是通过在类对象中增加一个指向 int 型的指针,这个指针指向的那个 int 即是计数,记录指针指向的那块内存被几个对象共用着。
采用引用计数,在构造函数、析构函数、拷贝构造函数、复制运算符中,都要对这个指向 int 的指针进行操作,并且需要判断指针指针指向 int 的变化情况,当为 0 时,则要释放掉指针指向的内存。
 1  #include  < iostream >
 2  #include  < cstring >
 3  using   namespace  std;
 4 
 5  class  str
 6  {
 7  private :
 8       char *  s_;
 9       int *  pcount_;
10  public :
11      str( const   char *  s  =   "" )
12      {
13          s_  =   new   char [strlen(s)  +   1 ];
14           if  (s_  !=   0 )
15          {
16              strcpy(s_, s);
17              pcount_  =   new   int ;
18               if  (pcount_  !=   0 )
19              {
20                   * pcount_  =   1 ;
21              }
22          }
23      }
24      str( const  str &  s)
25      {
26          s_  =  s.s_;
27          pcount_  =  s.pcount_;
28           ++ ( * pcount_);
29      }
30      str &   operator   =  ( const  str &  s)
31      {
32           if  ( this   !=   & s)
33          {
34               -- ( * pcount_);
35               if  ( * pcount_  ==   0 )
36              {
37                   if  (s_  !=   0 )
38                  {
39                      delete [] s_;
40                      s_  =   0 ;
41                  }
42                  delete pcount_;
43                  pcount_  =   0 ;
44              }
45              s_  =  s.s_;
46              pcount_  =  s.pcount_;
47               ++ ( * pcount_);
48          }
49           return   * this ;
50      }
51       ~ str()
52      {
53           -- ( * pcount_);
54           if  ( * pcount_  ==   0 )
55          {
56               //  cout << "test" << endl;
57               if  (s_  !=   0 )
58              {
59                  delete [] s_;
60                  s_  =   0 ;
61              }
62              delete pcount_;
63              pcount_  =   0 ;
64          }
65      }
66       char *  sr()  const
67      {
68           return  s_;
69      }
70  };
71 
72  ostream &   operator   <<  (ostream &   out const  str &  s)
73  {
74       out   <<  s.sr()  <<  endl;
75       return   out ;
76  }
77 
78  int  main()
79  {
80      str s1  =   " 123 " ;
81      str s2(s1);
82      cout  <<  s1  <<  endl;
83      cout  <<  s2  <<  endl;
84  }
85 



你可能感兴趣的:(关于含有成员指针的类的复制控制)