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

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

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