string类内存分配的概念:

     string类中必有一个私有成员(char*),用户记录从堆上分配内存的地址,其在构造时分配内存,在析构时释放内存;string类在返回这块内存地址时,只返回const char*,也就是只读的,如果你要写,你只能通过string提供的方法进行数据的改写。

在string类中,要实现写时才拷贝,需要解决两个问题,一个是内存共享,一个是Copy-On-Wirte(COW)。

     1、什么时候内存共享:a)以别的类构造自己,b)以别的类赋值。第一种情况时会触发拷贝构造函数,第二种情况会触发赋值操作符。

     2、Copy-On-Wirte(COW) 原理:Copy-On-Write一定使用了“引用计数”,当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,当有类析构时,这个计数会减一,直到最后一个类析构时,此时的引用计数为1或是0,此时,程序才会真正的Free这块从堆上分配的内存。

                                    

     当我们为string分配内存时,我们总是要多分配一个空间用来存放这个引用计数的值(初始为0),只要发生拷贝构造可是赋值时,这个内存的值就会加1。而在内容修改时,string类为查看这个引用计数是否为0,如果不为零,表示有人在共享这块内存,那么自己需要先做一份拷贝,然后把引用计数减去1,再把数据拷贝过来。

注意:读时也拷贝的情况

     当你通过迭代器或[ ]获取到string的内部地址的时候,string并不知道你将是要读还是要写。这是它无法确定,为此,当你获取到内部引用后,为了避免不能捕获你的写操作,它在此时废止了写时才拷贝技术!