`
feipigwang
  • 浏览: 741831 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

标准C++类string的Copy-On-Write技术(二)

阅读更多

2.2、 深入

在深入这前,通过上述的演示,我们应该知道在string类中,要实现写时才拷贝,需要解决两个问题,一个是内存共享,一个是Copy-On-Wirte,这两个主题会让我们产生许多疑问,还是让我们带着这样几个问题来学习吧:

1、 Copy-On-Write的原理是什么?

2、 string类在什么情况下才共享内存的?

3、 string类在什么情况下触发写时才拷贝(Copy-On-Write?

4、 Copy-On-Write时,发生了什么?

5、 Copy-On-Write的具体实现是怎么样的?

喔,你说只要看一看STLstirng的源码你就可以找到答案了。当然,当然,我也是参考了string的父模板类basic_string的源码。但是,如果你感到看STL的源码就好像看机器码,并严重打击你对C++自信心,乃至产生了自己是否懂C++的疑问,如果你有这样的感觉,那么还是继续往下看我的这篇文章吧。

OK,让我们一个问题一个问题地探讨吧,慢慢地所有的技术细节都会浮出水面的。

2.3、 Copy-On-Write的原理是什么?

有一定经验的程序员一定知道,Copy-On-Write一定使用了“引用计数”,是的,必然有一个变量类似于RefCnt。当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,当有类析构时,这个计数会减一,直到最后一个类析构时,此时的RefCnt1或是0,此时,程序才会真正的Free这块从堆上分配的内存。

是的,引用计数就是string类中写时才拷贝的原理!

不过,问题又来了,这个RefCnt该存在在哪里呢?如果存放在string类中,那么每个string的实例都有各自的一套,根本不能共有一个RefCnt,如果是声明成全局变量,或是静态成员,那就是所有的string类共享一个了,这也不行,我们需要的是一个“民主和集中”的一个解决方法。这是如何做到的呢?呵呵,人生就是一个糊涂后去探知,知道后和又糊涂的循环过程。别急别急,在后面我会给你一一道来的。

2.3.1、 string类在什么情况下才共享内存的?

这个问题的答案应该是明显的,根据常理和逻辑,如果一个类要用另一个类的数据,那就可以共享被使用类的内存了。这是很合理的,如果你不用我的,那就不用共享,只有你使用我的,才发生共享。

使用别的类的数据时,无非有两种情况,1)以别的类构造自己,2)以别的类赋值。第一种情况时会触发拷贝构造函数,第二种情况会触发赋值操作符。这两种情况我们都可以在类中实现其对应的方法。对于第一种情况,只需要在string类的拷贝构造函数中做点处理,让其引用计数累加;同样,对于第二种情况,只需要重载string类的赋值操作符,同样在其中加上一点处理。

唠叨几句:

1)构造和赋值的差别

对于前面那个例程中的这两句:

string str1 = "hello world";

string str2 = str1;

不要以为有“=”就是赋值操作,其实,这两条语句等价于:

string str1 ("hello world"); //调用的是构造函数

string str2 (str1); //调用的是拷贝构造函数

如果str2是下面的这样情况:

string str2; //调用参数默认为空串的构造函数:string str2(“”);

str2 = str1; //调用str2的赋值操作:str2.operator=(str1);

2) 另一种情况

char tmp[]=”hello world”;

string str1 = tmp;

string str2 = tmp;

这种情况下会触发内存的共享吗?想当然的,应该要共享。可是根据我们前面所说的共享内存的情况,两个string类的声明和初始语句并不符合我前述的两种情况,所以其并不发生内存共享。而且,C++现有特性也无法让我们做到对这种情况进行类的内存共享。

2.3.2、 string类在什么情况下触发写时才拷贝(Copy-On-Write?

哦,什么时候会发现写时才拷贝?很显然,当然是在共享同一块内存的类发生内容改变时,才会发生Copy-On-Write。比如string类的[]=+=+、操作符赋值,还有一些string类中诸如insertreplaceappend等成员函数,包括类的析构时。

修改数据才会触发Copy-On-Write,不修改当然就不会改啦。这就是托延战术的真谛,非到要做的时候才去做。

2.3.3、 Copy-On-Write时,发生了什么?

我们可能根据那个访问计数来决定是否需要拷贝,参看下面的代码:

If ( RefCnt>0 ) {

char* tmp = (char*) malloc(strlen(_Ptr)+1);

strcpy(tmp, _Ptr);

_Ptr = tmp;

}

上面的代码是一个假想的拷贝方法,如果有别的类在引用(检查引用计数来获知)这块内存,那么就需要把更改类进行“拷贝”这个动作。

我们可以把这个拷的运行封装成一个函数,供那些改变内容的成员函数使用。

<-上一页 下一页->

(版权所有,转载时请注明作者和出处)

分享到:
评论

相关推荐

    标准C++类string的Copy-On-Write技术

    里,我想从C++类或是设计模式的角度为各位揭开Copy-On-Write技术在string中实现的面纱,以供各位在用C++进行类库设计时做一点参考

    STL 的string类怎么啦

    老实说,我几年前也有同样的痛苦(就是当我写下《标准C++类string的Copy-On-Write技术》之前的一段时间)。那时,我不得不研究那根本不是给人看的SGI出品的string类的源码,代码的可读性几乎为零,而且随着了解越...

    Turbo C++ 3.0[DISK]

    special offer, and write for full details on how to receive a free IntroPak containing a $15 credit toward your first month's on-line charges. 2. Check with your local software dealer or users' ...

    Turbo C++ 3.00[DISK]

    special offer, and write for full details on how to receive a free IntroPak containing a $15 credit toward your first month's on-line charges. 2. Check with your local software dealer or users' ...

    C++MFC教程

    Visual C++MFC入门教程 目录 +-- 第一章 VC入门 |------ 1.1 如何学好VC |------ 1.2 理解Windows消息机制 |------ 1.3 利用Visual C++/MFC开发Windows程序的优势 |------ 1.4 利用MFC进行开发的通用方法介绍 |----...

    Senfore_DragDrop_v4.1

    Earlier versions of Delphi and C++ Builder will not be supported. If you need Delphi 3 or C++ Builder 3 support you will have to revert to version 3.7 of the Drag and Drop Component Suite. The ...

    Google C++ Style Guide(Google C++编程规范)高清PDF

    Classes Doing Work in Constructors Default Constructors Explicit Constructors Copy Constructors Structs vs. Classes Inheritance Multiple Inheritance Interfaces Operator Overloading Access Control ...

    C++中sting类的简单实现方法

    析构函数,赋值运算符重载,运算符+=的重载,运算符[]的重载,c_str(得到一个C风格的字符指针,可操作字符串),Size,Push_Back,Insert(深拷贝),以及用写时拷贝copy_on_write的方式实现基本的String类 深拷贝的方式

    From C to C++

    // convert a string to uppercase! #include #define N 200 int main(){ char ms[N]; int i; printf("Input ms: "); gets(ms); for(i=0;ms[i];i++) if(ms[i]&gt;='a'&&ms[i]) ms[i]-='\x20'; puts(ms); ...

    FastReport.v4.15 for.Delphi.BCB.Full.Source企业版含ClientServer中文修正版支持D4-XE5

    FastReport® VCL is an add-on component that allows your application to generate reports quickly and efficiently. FastReport® provides all the tools necessary for developing reports, including a ...

    acpi控制笔记本风扇转速

    produced when this parameter was a null string (""). Now, the original input filename is used as the AML output filename, with an ".aml" extension. Implemented a generic batch command mode for the ...

    C++大学教程,一本适合初学者的入门教材(part1)

    第7章 类与数据抽象(二) 7. 1 简介 7.2 const(常量)对象与const成员函数 7.3 复合:把对象作为类成员 7.4 友元函数与友元类 7.5 使用this指针 7.6 动态内存分配与new和delete运算符 7.7 static类成员 7.8 ...

    au3反编译源码

    To copy text or to enlarge the log window double click on it. Supported Obfuscators: 'Jos van der Zande AutoIt3 Source Obfuscator v1.0.14 [June 16, 2007]' , 'Jos van der Zande AutoIt3 Source ...

    C++大学教程,一本适合初学者的入门教材(part2)

    第7章 类与数据抽象(二) 7. 1 简介 7.2 const(常量)对象与const成员函数 7.3 复合:把对象作为类成员 7.4 友元函数与友元类 7.5 使用this指针 7.6 动态内存分配与new和delete运算符 7.7 static类成员 7.8 ...

    c/c++函数库说明(api)html版

    所有的 C / C++ 函数 Constructors (cppstring) Constructors (cppvector) Operators (cppbitset) Operators (cppdeque) Operators (cppstack) Operators (cppstring) Operators (cppvector) abort (stdother...

    一个跨平台的CString源码

    // the Standard C++ Library basic_string&lt;&gt; template and add to it the // the following conveniences: // - The full MFC CString set of functions (including implicit cast) // - writing to/reading ...

    FlexGraphics_V_1.79_D4-XE10.2_Downloadly.ir

    on a curve by the distance from the original point on the perimeter. - ADD: Added the method TCustomProp.GetPublishedComplexProp - returns included complex flex-property by name registered through ...

    RxLib控件包内含RxGIF,全部源码及DEMO

    TFormStorage allows you to read and write virtually any component published property to an INI file or the system Registry with virtually no code. Works with 3rd party and your own custom controls as ...

    Linux多线程服务端编程:使用muduo C++网络库

    2.8借shared_ptr 实现copy-on-write. . . . . . . . . . . . . . . . . . . . . . 52 第3章多线程服务器的适用场合与常用编程模型 3.1进程与线程. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . ...

Global site tag (gtag.js) - Google Analytics