• 浅拷贝&深拷贝&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』
  • 相关阅读:
    iOS使用自签名证书实现HTTPS请求
    DB操作-用批处理执行Sql语句
    SSL通信-忽略证书认证错误
    oracle 19c awr 丢失 i/o信息
    this.$route.query刷新后类型改变
    wx.navigateTo在app.js中偶发性失效
    微信小程序new Date()转换日期格式时iphonex为NaN
    下载cnpm成功,cnpm -v却不识别
    element-ui的表单验证如何清除校验提示语
    5. 最长回文子串(动态规划算法)
  • 原文地址:https://www.cnblogs.com/-zyj/p/String.html
Copyright © 2020-2023  润新知