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

推荐订阅源

N
News and Events Feed by Topic
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs
博客园 - 叶小钗
P
Privacy International News Feed
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
IT之家
IT之家
博客园 - 聂微东
Know Your Adversary
Know Your Adversary
Help Net Security
Help Net Security
罗磊的独立博客
I
Intezer
S
Schneier on Security
博客园_首页
C
CERT Recently Published Vulnerability Notes
雷峰网
雷峰网
Cisco Talos Blog
Cisco Talos Blog
宝玉的分享
宝玉的分享
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Webroot Blog
Webroot Blog
TaoSecurity Blog
TaoSecurity Blog
MyScale Blog
MyScale Blog
P
Privacy & Cybersecurity Law Blog
T
The Exploit Database - CXSecurity.com
PCI Perspectives
PCI Perspectives
Security Latest
Security Latest
H
Heimdal Security Blog
S
Secure Thoughts
Hacker News: Ask HN
Hacker News: Ask HN
Y
Y Combinator Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
SecWiki News
SecWiki News
The GitHub Blog
The GitHub Blog
A
Arctic Wolf
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
T
Threat Research - Cisco Blogs
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

博客园 - 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;
}