写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配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. 解决PowerDesigner中DBMS选项卡为空白

    点击DBMS后面的黄色(浏览)文件图标, 找到安装目录里面PowerDesigner \Resource Files\DBMS,就可以了.

  2. jQuery 图片跟着鼠标动

    html默认鼠标样式改成图片时格式为 .ani 图片跟随鼠标挪动 html <div id="mouseImg"> <img src="images/问 ...

  3. Python traceback模块简单使用

    Python中的traceback模块被用于跟踪异常返回信息,可以在logging中记录下traceback. traceback.format_exc() 获取异常为字符串,保存到日志文件 try: ...

  4. Python中基于socketserver实现并发的socket

    1.基于TCP协议: 服务端: import socketserver class MyHandler(socketserver.BaseRequestHandler): def handle(sel ...

  5. 20-1 django上传文件和项目里上传头像如何查看

    一 普通上传方式 1 views def upload(request): if request.method == "POST": # print(request.POST) # ...

  6. Xib设计UITableViewCell然后动态加载

    转自: http://www.2cto.com/kf/201202/120764.html (注:环境Mac OS X Lion 10.7.3 + Xcode 4.2.1 + iOS SDK 5.0. ...

  7. PHP中__FUNCTION__与__METHOD__的区别

    你知道php中__FUNCTION__与__METHOD__的区别吗?本文通过一个小例子,为大家介绍下二者的区别,有兴趣的朋友可以参考下.   PHP中__FUNCTION__与__METHOD__的 ...

  8. Getting started with the basics of programming exercises_2

    1.编写简单power函数 #include<stdio.h> int power(int m, int n); // test power function int main(void) ...

  9. @noi.ac - 443@ 老头子的话

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 老头子是小学校长,小学生(大哥)们都很听老头子的话.一天,老头子 ...

  10. JS遍历数组

    for 如果用var会造成变量声明提前等问题for(var i = 1; i <= arr.length; i++){ console.log(arr[i - 1]);} for(let i = ...