写时拷贝(方案一)

深拷贝效率低,我们可以应引用计数的方式去解决浅拷贝中析构多次的问题。

首先要清楚写时拷贝是利用浅拷贝来解决问题!!

方案一

class String
{
private:
    char* _str;
    int _refCount;
};

方案一最不靠谱,它将用作计数的整形变量_refCount定义为类的私有成员变量,任何一个对象都有它自己的成员变量_refCount,它们互不影响,只要拷贝出了对象,_refCount大于了1,那么每个对象调用自己的析构函数时--_refCount不等于0,那么它们指向的那块内存都将得不到释放,无法达到我们要的效果。

//以下是对方案一的简单实现,大家可以结合上图感受到方案一的缺陷

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
using namespace std;
#include<assert.h>

class String
{
public:
    String(char* str = "")    //不能strlen(NULL)
       :_refCount(0)
    {
       _str = new char[strlen( str) + 1];
       strcpy(_str, str);
       _refCount++;
    }
    String(String &s)
       :_refCount( s._refCount)     
    {
       _str = s._str;
       _refCount++;
       s._refCount = _refCount;
       
       //这里虽然可以让两个对象的_refCount相等,
       //但如果超过两个对象的_str指针都指向同一块内存时,
       //就无法让所有对象的_refCount都保持一致
       //这是方案一的缺陷之一
    }
    ~String()
    {
       if (--_refCount == 0)
       {
            delete[] _str;
           _str = NULL;
           cout << "~String " << endl;
       }
    }
    friend ostream& operator<<( ostream& output, const String &s);
private:
    char* _str;
    int _refCount;
};
ostream& operator<<( ostream& output, const String & s)
{
    output << s._str;
    return output;
}
void Test()
{
    String s1("aaa");
    String s2(s1);
    String s3(s2);
    cout << s1 << endl;
    cout << s2 << endl;
    cout << s3 << endl;
}
int main()
{
    Test();
    system("pause");
    return 0;
}

以下是其它方案链接地址:

方案二:

http://iynu17.blog.51cto.com/10734157/1755185

方案三:

http://iynu17.blog.51cto.com/10734157/1755208

方案四:(推荐)

http://iynu17.blog.51cto.com/10734157/1755213

时间: 2024-11-05 16:53:57

写时拷贝(方案一)的相关文章

分析 写时拷贝 的四个方案(Copy On Write)

深拷贝效率低,我们可以应引用计数的方式去解决浅拷贝中析构多次的问题. 首先要清楚写时拷贝是利用浅拷贝来解决问题!! 方案一 class String { private: char* _str; int _refCount; }; 方案一最不靠谱,它将用作计数的整形变量_refCount定义为类的私有成员变量,任何一个对象都有它自己的成员变量_refCount,它们互不影响,只要拷贝出了对象,_refCount大于了1,那么每个对象调用自己的析构函数时--_refCount不等于0,那么它们指向

深拷贝&amp;浅拷贝&amp;引用计数&amp;写时拷贝

(1).浅拷贝: class String { public: String(const char* str="") :_str(new char[strlen(str)+1]) { strcpy(_str,str); } ~String() { if(NULL!=_str) { delete[] _str; _str=NULL; } } private: char* _str; }; int main() { String s1("hello"); String

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

1.传统的fork()函数创建一个子进程,子进程和父进程共享正文段,复制数据段,堆,栈到子进程示意图如下: 2.Linux的fork()函数-写时复制(copy-on-write)创建一个子进程,内核只为子进程创建虚拟空间,不分配物理内存,和父进程共享物理空间,当父进程中有更改相应段的行为发生时,才为子进程分配物理空间.示意图如下: 3.vfork()函数创建一个子进程,共享父进程的一切.示意图如下: 4.传统fork与copy-on-write区别 传统的fork函数直接把所有资源复制给新的进

写时拷贝技术

Copy On Write(COW):写时拷贝技术 一.什么是写时拷贝技术: 写时拷贝技术可以理解为"写的时候才去分配空间",这实际上是一种拖延战术. 举个栗子: 二.写时拷贝技术原理: 写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数减一(假装释放),直到引用计数减为0时才真的释放掉这块空间.当有的指针要改变这块空间的值时,再为这个指针分配自

写时拷贝 引用计数器模型

1.深浅拷贝的使用时机: 浅拷贝:对只读数据共用一份空间,且只释放一次空间: 深拷贝:数据的修改,的不同空间: 2.引用计数器模型 使用变量use_count,来记载初始化对象个数: (1).static模型(此处只用浅拷贝与浅赋值) #include<iostream> #include<string.h> #include<malloc.h> using namespace std; class String{ public:     String(const ch

Linux写时拷贝技术【转】

本文转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html COW技术初窥: 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程. 那么子进程的物理空间没有代码,怎么去取指令执行exec系统调用呢? 在fork之后exec之前两个进

写时拷贝(copy on write)

;写时拷贝(copy on write) 即某个对象的堆指针成员平时和其他对像的堆指针成员平时它们几个共享同一份实值 ,知道这个独享的值必须发生改写的时候才停止共享,而将该值重新申请一份空间存放自己私有的东西

简单的String类实现及写时拷贝

#include<iostream> using namespace std; class String { public: /*String(const char* str=" ") :_str(new char[strlen(str)+1]) { strcpy(_str, str); } */ String(const char* str = " ") { if (str == NULL) { _str = new char; _str[0] = '

String写时拷贝实现

头文件部分 1 /* 2 版权信息:狼 3 文件名称:String.h 4 文件标识: 5 摘 要:对于上版本简易的String进行优化跟进. 6 改进 7 1.(将小块内存问题与大块分别对待)小内存块每个对象都有,当内存需求大于定义大小时利用动态分配 8 2.实现大块内存的写时拷贝功能,提高效率,优化空间利用 9 3.类似new[]实现机制:将动态内存块大小信息保存为隐藏“头” 10 11 当前版本:1.2 12 修 改 者:狼 13 完成日期:2015-12-12 14 15 取代版本:1.