深入理解CC++中的写时拷贝

深入理解CC++中的写时拷贝,第1张

概述写时拷贝何为写时拷贝?前面我说过深拷贝浅拷贝,今天我们来探究一下写时拷贝。深拷贝是补充了浅拷贝的不足,写时拷贝其实也就是补充一点深拷贝的不足。其实写时拷贝的意思就是:当你读取到这个空间的时候,并不会开

写时拷贝

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

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

写时拷贝的实用:实现一个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,等, 你在使用[]之后再使用迭代器之后,引用就有可能失效了。

总结

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

总结

以上是内存溢出为你收集整理的深入理解C/C++中的写时拷贝全部内容,希望文章能够帮你解决深入理解C/C++中的写时拷贝所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1245246.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存