浅拷贝&深拷贝&Copy On Write(Sring类)

String类的三种实现

  •   浅拷贝

 

 1 class String
 2 {
 3 public:
 4     String(const char* pdata)//构造函数
 5         :_pdata(new char[strlen(pdata) + 1])
 6     {
 7         strcpy(_pdata, pdata);
 8     }
 9     String(const String&s)//拷贝构造
10         :_pdata(s._pdata)
11     {}
12     ~String()//析构函数
13     {
14         if (NULL != _pdata)
15         {
16             delete[]_pdata;
17             _pdata = NULL;
18         }
19     }
20     String &operator=(const String&s)
21     {
22         //检查自赋值
23         if (this != &s)
24         {
25             char*temp = new char[strlen(s._pdata) + 1];
26             strcpy(temp, s._pdata);
27             delete[]_pdata;
28             _pdata = temp;
29         }
30         return *this;
31     }
32 private:
33     char*_pdata;
34 };
35 void main()
36 {
37     String s1 ("hello world");
38     String s2=s1;
39 }

     当类里面有指针对象时,进行简单赋值的浅拷贝,两个对象指向同一块内存,存在崩溃的问题!这里我们要进行深拷贝。

  • 深拷贝

 

 1 # define _CRT_SECURE_NO_WARNINGS
 2 #include<iostream>
 3 #include<string>
 4 using namespace std;
 5 class String
 6 {
 7 public:
 8     String(const char* pdata)//构造函数
 9         :_pdata(new char[strlen(pdata) + 1])
10     {
11         strcpy(_pdata, pdata);
12     }
13     String(const String&s)//拷贝构造
14         :_pdata(new char[strlen(s._pdata) + 1])
15     {
16         strcpy(_pdata, s._pdata);
17     }
18     ~String()//析构函数
19     {
20         if (NULL != _pdata)
21         {
22             delete[]_pdata;
23             _pdata = NULL;
24         }
25     }
26     String &operator=(const String&s)
27     {
28         //检查自赋值
29         if (this != &s)
30         {
31             char*temp = new char[strlen(s._pdata) + 1];
32             strcpy(temp, s._pdata);
33             delete[]_pdata;
34             _pdata = temp;
35         }
36         return *this;
37     }
38 private:
39     char*_pdata;
40 };
41 //简洁版
42 class String
43 {
44 public:
45     String(const char* pData)
46         : _pData(new char[strlen(pData) + 1])
47     {
48         strcpy(_pData, pData);
49     }
50 
51     String(const String& s)
52         : _pData(NULL)
53     {
54         String temp(s._pData);
55         std::swap(_pData, temp._pData);
56     }
57 
58      String& operator=(const String& s)
59          {
60              if (this != &s)
61              {
62                  String temp(s._pData);
63                  std::swap(_pData, temp._pData);
64              }
65              return *this;
66          }
67      ~String()
68      {
69          if (NULL != _pData)
70          {
71              delete[] _pData;
72              _pData = NULL;
73          }
74      }
75 private:
76     char* _pData;
77 };
78 void main()
79 {
80     String s1 ("hello world");
81     String s2=s1;
82 }

  • 写时拷贝

   

 1 #include<iostream>
 2 #include<string.h>
 3 #include<assert.h>
 4 namespace COW
 5 {
 6     class String
 7     {
 8     public:
 9         String(const char* pData)
10             : _pData(new char[strlen(pData) + 1])
11             , _refCount(new int)
12         {
13             *_refCount = 1;
14             strcpy(_pData, pData);
15         }
16 
17         // String s2(s1);
18         String(String& s)
19             : _pData(s._pData)
20             , _refCount(s._refCount)
21         {
22             ++(*_refCount);
23         }
24 
25         // s1 = s2;
26         String& operator=(String s)
27         {
28             if (this != &s)
29             {
30                 if (--(*_refCount) == 0)
31                 {
32                     delete[] _pData;
33                     delete _refCount;
34                 }
35 
36                 _pData = s._pData;
37                 _refCount = s._refCount;
38                 ++(*_refCount);
39             }
40 
41             return *this;
42         }
43 
44         ~String()
45         {
46             if (--(*_refCount) == 0)
47             {
48                 delete[] _pData;
49                 delete _refCount;
50             }
51         }
52         // 返回值  函数名(参数)
53         char& operator[](int index)
54         {
55             // 检测返回
56             // *_refCount > 1
57             // *_refCount = 1
58             if (*_refCount > 1)
59             {
60                 (*_refCount)--;
61                 String temp(_pData);
62                 _pData = temp._pData;
63                 _refCount = temp._refCount;
64                 (*_refCount)++;
65             }
66             return _pData[index];
67         }
68         /*const char& operator[](int index)const 
69         {
70             
71             return _pData[index];
72         }*/
73     private:
74         char* _pData;
75         int* _refCount;
76     };
77 }
78 void FunTest()
79 {
80     COW::String s1("12345");
81     COW::String s2("123456789");
82     const COW::String s3 = s2;
83     s1 = s2;
84     s2[0] = '6';
85     //std::cout << s3[1];
86 }
87 int main()
88 {
89     FunTest();
90     return 0;
91 }

 

  string 之间拷贝时不是深拷贝,只拷贝了指针, 也就是共享同一个字符串内容, 只有在内容被修改的时候, 才真正分配了新的内存并 copy 。 比如 s[0]='1' 之类的修改字符串内容的一些write操作, 就会申请新的内容,和之前的共享内存独立开。 所以称之为 『copy-on-write』
posted @ 2016-04-19 14:32  A_carat_tear  阅读(427)  评论(0编辑  收藏  举报