惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
阮一峰的网络日志
阮一峰的网络日志
量子位
雷峰网
雷峰网
宝玉的分享
宝玉的分享
V
Visual Studio Blog
博客园_首页
小众软件
小众软件
The Cloudflare Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
S
SegmentFault 最新的问题
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
WordPress大学
WordPress大学

博客园 - cpunion

使用dpkt和pcap抓包 [收藏] jfwan实现的一个C++委托类 [c++] c++0x中的auto和typeof ACE_TP_Reactor的限制 ACE_SOCK_Stream send和recv超时设置 哀悼18位在车祸中死去的人 对ACE_TP_Reactor定时器处理机制做一点修改。 C++编写“异步调用代理组件”的一点想法 有趣的东西:Test () () () () () () () () () (); - cpunion VC2005 Beta 2 模板偏特化有些问题 [python] and or 表达式陷阱一则。 Media Player Classic外挂字幕时间调整脚本 我们的标准化委员会网站在哪? 不就是个座嘛 answers.com真是个不错的网站 《星际之门》和《亚特兰蒂斯》总算是更新了 生成gb2312码表 - cpunion - 博客园 [假如设计一个新语言] 哪些语言特性是我想要的 Python写的一个适配器类。
写一个CopyOnWrite的通用实现(C++) - cpunion - 博客园
cpunion · 2005-07-29 · via 博客园 - cpunion

这项技术最常用的是字符串类,如下:
string s1 ("long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long string");
string s2 = s1;   /
如果直接复制字符串缓冲区,那么会极大地损失效率,所以一般不这么做,而是让2个字符串共享同一个数据,当某个字符串对象要修改缓冲区时,再给它复制一份。

实现了一个简单的CopyOnWrite类,并用vector模拟了一个字符串,当然还没写完它,也只模拟了CopyOnWrite部分。


#include <vector>
#include 
<iostream>
#include 
<cassert>
using namespace std;#define DEBUG_TEST

#ifdef DEBUG_TEST
# define TRACE1(x) cout 

<< x << endl
# define TRACE2(x,y) cout 
<< x << y << endl
#endif

template 

<typename T>
class CopyOnWriteData
{
    size_t    _ref_count;
    T        _data;

    CopyOnWriteData (

const CopyOnWriteData& data)
        : _ref_count (
1), _data(data._data)
    {
        TRACE2 (
"CopyOnWriteData (const CopyOnWriteData& data) | "this);
    }

    CopyOnWriteData

& operator = (const CopyOnWriteData& data);
public:
    CopyOnWriteData ()
        : _ref_count (
0)
    {
        TRACE2 (
"CopyOnWriteData () | "this);
    }

    CopyOnWriteData (T data)
        : _ref_count (

1), _data(data)
    {
        TRACE2 (
"CopyOnWriteData (T data) | "this);
    }
~CopyOnWriteData ()
    {
        TRACE2 (
"~CopyOnWriteData () | "this);
        release ();
    }

    CopyOnWriteData

* copy ()
    {
        CopyOnWriteData
* cp = new CopyOnWriteData (*this);
        release ();
        
return cp;
    }

    T

& data ()
    {
        
return _data;
    }

    size_t ref_count () 

const
    {
        
return _ref_count;
    }

    size_t addRef ()
    {

return ++ _ref_count;
    }

    size_t release ()
    {

return -- _ref_count;
    }
};

template 

<typename T>
struct CopyOnWrite
{
    CopyOnWriteData
<T>* holder;void auto_copy ()
    {
        
if (holder->ref_count () > 1)
            holder 
= holder->copy ();
    }

    CopyOnWrite (CopyOnWriteData

<T>* p = 0)
        : holder (p)
    {
        TRACE2 (
"CopyOnWrite (CopyOnWriteData<T>* p = 0) | "this);
        
if (holder)
            holder
->addRef ();
    }

    CopyOnWrite (

const CopyOnWrite& o)
        : holder (o.holder)
    {
        TRACE2 (
"CopyOnWrite (const CopyOnWrite& o) | "this);
        
if (holder)
            holder
->addRef ();
    }

    CopyOnWrite

& operator = (const CopyOnWrite& o)
    {
        TRACE2 (
"CopyOnWrite& operator = (const CopyOnWrite& o) | "this);
        cout 
<< "" << this << endl;
        holder 
= o.holder;
        
if (holder)
            holder
->addRef ();
        
return *this;
    }
~CopyOnWrite ()
    {
        TRACE2 (
"~CopyOnWrite () | "this);
        
if (holder)
            holder
->release ();
        
if (!holder->ref_count ())
            delete holder;
    }
};
class String
{
#ifdef DEBUG_TEST
public:
#endif
    CopyOnWrite 
<vector<char> > _data;
public:
    String (
const char* p = 0)
    {
        TRACE2 (
"String (const char* p = 0) | "this);
        _data.holder 
= new CopyOnWriteData<vector<char> >;
        
if (!p)
        {
            _data.holder
->data ().push_back ('\0');
        }
        
else
        {
            size_t len 
= strlen(p) + 1;
            copy (p, p 
+ len, back_insert_iterator <vector<char> > (_data.holder->data ()));
        }
        _data.holder
->addRef ();
    }

    String (

const String& o)
        : _data (o._data)
    {
        TRACE2 (
"String (const String& o) | "this);
    }

    String

& operator = (const String& o)
    {
        TRACE2 (
"String& operator = (const String& o) | "this);
        _data 
= o._data;
        
return *this;
    }
~String ()
    {
        TRACE2 (
"~String () | "this);
    }
const char* c_str () const
    {
        
return (const char*)&_data.holder->data ()[0];
    }

    size_t find (

const char* fstr) const
    {
        
// 
    }void append (const char* p)
    {
        _data.auto_copy ();
        
// 
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    String s (
"hello");
    assert (s._data.holder
->ref_count () == 1);
    String s1 
= s;

    assert (s._data.holder

->ref_count () == 2);
    assert (s1._data.holder
->ref_count () == 2);
    String s2 (s);
    assert (s._data.holder
->ref_count () == 3);
    assert (s1._data.holder
->ref_count () == 3);
    assert (s2._data.holder
->ref_count () == 3);

    assert (strcmp (

"hello", s.c_str ()) == 0);

    assert (s._data.holder 

== s1._data.holder);
    assert (s2._data.holder 
== s1._data.holder);

    s.append (

"aa");
    assert (s._data.holder
->ref_count () == 1);
    assert (strcmp (
"hello", s.c_str ()) == 0);
    assert (s1._data.holder
->ref_count () == 2);
    assert (strcmp (
"hello", s.c_str ()) == 0);
    assert (s2._data.holder
->ref_count () == 2);
    assert (strcmp (
"hello", s.c_str ()) == 0);return 0;
}