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

#include<iostream>
#include<new.h>
#include<string>
using namespace std; //1解决内存泄漏
//2编写赋值语句
//3写时拷贝
class String;
ostream& operator<<(ostream &out, const String &s); /////////////////////////////////////////////////////////////////////
class String_rep
{
friend class String;
friend ostream& operator<<(ostream &out, const String &s); private:
String_rep(const char *str = "") : use_count_()
{
if (str == NULL)
{
data = new char[];
data[] = '\0';
}
else
{
data = new char[strlen(str) + ];
strcpy(data, str);
}
}
String_rep(const String_rep &rep)
{
this->data = rep.data;
}
String_rep& operator=(const String_rep &rep)
{
this->data = rep.data;
}
~String_rep()
{
if (data != NULL)
{
delete[]data;
data = NULL;
}
}
public:
void increment()
{
++use_count_;
} void decrement()
{
//引用计数为0,释放共享内存
if (--use_count_ == )
delete this;
} private:
char *data;
int use_count_;
}; //////////////////////////////////////////////////////
class String
{
friend ostream& operator<<(ostream& out, const String &s); public:
String(const char *str = "") :rep(new String_rep(str))
{
rep->increment();
}
String(const String &s)
{
rep = s.rep;
rep->increment();
}
String& operator=(const String &s)
{
if (&s != this)
{
this->rep->decrement(); //原有共享内存中的引用计数减一
this->rep = s.rep;
this->rep->increment(); //现有引用计数加一
}
return *this;
}
~String()
{
//String析构一次,引用计数减一
rep->decrement();
} public:
void to_upper();
String& operator+=(const String &str); private:
String_rep *rep;
}; /////////////////////////////////////////////////////////////////////////
ostream& operator<<(ostream &out, const String &s)
{
out << s.rep->data;
return out;
} //创建新的共享内存原来共享内存中值一样,然后再修改
void String::to_upper()
{
String *newStr = new String(this->rep->data);
this->rep->decrement();
this->rep = newStr->rep;
this->rep->increment(); char *str = this->rep->data;
while (*str != '\0')
{
*str -= ;
++str;
}
delete newStr;
} String& String::operator+=(const String &str)
{
char *ch = new char[strlen(str.rep->data) + strlen(this->rep->data) + ];
strcpy(ch,this->rep->data);
strcat(ch, str.rep->data); this->rep->decrement();
String_rep *s = new String_rep(ch);
this->rep = s;
this->rep->increment(); return *this;
} int main()
{
String s("abc");
String s1;
s1 = s; //
String s2("xyz");
String s3(s);
s2.to_upper(); s3 += s2;
cout << s2 << endl;
cout << s3 << endl; return ;
}
 
 
 
 
 
 

写时拷贝COW(copy-on-write)的更多相关文章

  1. rust漫游 - 写时拷贝 Cow<'_, B>

    rust漫游 - 写时拷贝 Cow<'_, B> Cow 是一个写时复制功能的智能指针,在数据需要修改或者所有权发生变化时使用,多用于读多写少的场景. pub enum Cow<'a ...

  2. 写时拷贝(Copy On Write)方案详解

    本文旨在通过对 写时拷贝 的四个方案(Copy On Write)分析,让大家明白写时拷贝的实现及原理. 关于浅拷贝与深拷贝,我在之前的博客中已经阐述过了  浅拷贝容易出现指针悬挂的问题,深拷贝效率低 ...

  3. [转] Linux写时拷贝技术(copy-on-write)

    PS:http://blog.csdn.net/zxh821112/article/details/8969541 进程间是相互独立的,其实完全可以看成A.B两个进程各自有一份单独的liba.so和l ...

  4. Linux写时拷贝技术(copy-on-write)

    COW技术初窥: 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内 ...

  5. 【转】Linux写时拷贝技术(copy-on-write)

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html 源于网上资料 COW技术初窥: 在Linux程序中,fork()会 ...

  6. copy-on-write(写时拷贝技术)

    今天看<Unix环境高级编程>的fork函数与vfork函数时,看见一个copy-on-write的名词,貌似以前也经常听见别人说过这个,但也一直不明白这究竟是什么东西.所以就好好在网上了 ...

  7. Linux写时拷贝技术【转】

    本文转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html COW技术初窥: 在Linux程序中,fork()会产 ...

  8. String写时拷贝实现

    头文件部分 1 /* 版权信息:狼 文件名称:String.h 文件标识: 摘 要:对于上版本简易的String进行优化跟进. 改进 1.(将小块内存问题与大块分别对待)小内存块每个对象都有,当内存需 ...

  9. Rust写时复制Cow<T>

    写时复制(Copy on Write)技术是一种程序中的优化策略,多应用于读多写少的场景.主要思想是创建对象的时候不立即进行复制,而是先引用(借用)原有对象进行大量的读操作,只有进行到少量的写操作的时 ...

随机推荐

  1. HDU_1005:Number Sequence

    Problem Description A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1 ...

  2. 使用DataWorks调度DLA循环任务

    DataWorks是阿里云上的一款热门产品,可以为用户提供大数据开发调度服务.它支持了Data Lake Analytics(后文简称DLA)以后,DLA用户可以通过它进行定时任务调度,非常方便.本文 ...

  3. ArcMap影像纠偏

    客户给了一张PNG图,如下图,需要提取其中北极航线. 策略是ArcMap中先配准PNG,使之与底图较好重合.再新建线图层,描出航线.这种彩色丰富的图,很难用栅格转矢量的方式,故应用描边法. 一.配准P ...

  4. day1_python之字符串的常用操作

    python字符串操作常用操作,如字符串的替换.删除.截取.复制.连接.比较.查找.分割等,需要的朋友可以参考下. 1.去除空格 str.strip():删除字符串两边的指定字符,括号的写入指定字符, ...

  5. uva 10566 Crossed Ladders (二分)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  6. js常见运算符

    博客地址 :https://www.cnblogs.com/sandraryan/

  7. Ext--Layout(布局)

    EXT中的布局,常用的有border.column.fit.form.tabel这几种. Fit布局,子元素将自动填满整个父容器(对元素设置宽度无效),如果容器组件中有多个子元素,则只会显示第一个子元 ...

  8. hdu 5723 Abandoned country(2016多校第一场) (最小生成树+期望)

    Abandoned country Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  9. poj 1279 Art Gallery (Half Plane Intersection)

    1279 -- Art Gallery 还是半平面交的问题,要求求出多边形中可以观察到多边形所有边的位置区域的面积.其实就是把每一条边看作有向直线然后套用半平面交.这题在输入的时候应该用多边形的有向面 ...

  10. jq操作class类

    https://www.cnblogs.com/sandraryan/ 鼠标移入移除切换样式 方法一: css .menu { color: green; } .active { color: red ...