首页 > 编程 > C++ > 正文

深入理解C/C++中的写时拷贝

2020-05-23 13:49:24
字体:
来源:转载
供稿:网友

color: #ff0000">写时拷贝

何为写时拷贝? 前面我说过深拷贝浅拷贝,今天我们来探究一下写时拷贝。深拷贝是补充了浅拷贝的不足,写时拷贝其实也就是补充一点深拷贝的不足。其实写时拷贝的意思就是: 当你读取到这个空间的时候,并不会开辟出一个一模一样的空间出来给你,当你真正需要拷贝的时候,那么他就会开辟出空间给你。也就是拖延版的深拷贝。

c,深拷贝,拷贝文件夹,拷贝构造函数

写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(假装释放),直到引用计数减为0时才真的释放掉这块空间。当有的指针要改变这块空间的值时,再为这个指针分配自己的空间(注意这时引用计数的变化,旧的空间的引用计数减一,新分配的空间引用计数加一)。

c,深拷贝,拷贝文件夹,拷贝构造函数

写时拷贝的实用:实现一个string类

class String { public:  String(const char *str = "")  :_str(new char[strlen(str) + 1 + 4])  {  cout << "Sring()" << endl;  _str += 4;    //前4个字节用来存放引用计数  GetCount() = 1;   //引用计数的初始值设置成1  strcpy(_str, str);  }   String(String& s)  :_str(s._str)  {  cout << "Sring(String&)" << endl;  GetCount()++;  }   String& operator=(String& s)  {  cout << "Sring& operator=" << endl;   if (this != &s)  {   Release();   _str = s._str;   GetCount()++;  }  return *this;  }   ~String()  {  cout << "~Sring()" << endl;  Release();  } public:  char& operator[](size_t index)  {  if (GetCount() == 1)   //如果计数器为1,则直接返回  {   return _str[index];  }  GetCount()--;  char *tmp = _str;  _str = new char[strlen(tmp) + 1 + 4];  _str += 4;  strcpy(_str, tmp);  GetCount() = 1;  return _str[index];  } private:  int& GetCount()  {  return *(int *)(_str - 4);  }  void Release()  {  if (--GetCount() == 0)  {   cout << "释放" << endl;   delete[](_str - 4); //注意释放的时候还有 存放引用计数的4个字节   _str = NULL;  }  } private:  char *_str; }; 

这里有一个问题呢~,C++标准的确就是这样的,C++标准认为,当你通过迭代器或[]获取到string的内部地址的时候,string并不知道你将是要读还是要写。这是它无法确定,为此,当你获取到内部引用后,为了避免不能捕获你的写操作,它在此时废止了写时才拷贝技术。

这样看来我们在使用写时拷贝的时候,一定要注意,如果你不需要对string的内部进行修改,那你就千万不要使用通过[]操作符和迭代器去获取字符串的内部地址引用,如果你一定要这么做,那么你就必须要付出代价。当然,string还提供了一些使迭代器和引用失效的方法。比如说push_back,等, 你在使用[]之后再使用迭代器之后,引用就有可能失效了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对VEVB武林网的支持。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表