我们知道当自定义对象如果在堆上开空间,那么拷贝构造时会深拷贝,深拷贝会加大内存开销,用写实拷贝(也叫延迟拷贝)可以在深浅拷贝中取得平衡。
浅拷贝问题:
析构两次
一个对象修改会影响另一个
用引用计数来解决析构问题
拷贝构造时,先进行浅拷贝,S1和S2都是指向同一块空间,引用计数+1=2。当S2进行析构时如果引用计数大于1,则引用计数-1,如果引用计数等于1,则调用析构函数。
写实拷贝解决一个对象修改会影响另一个
当s2被修改时,引用计数-1,此时进行深拷贝
这个设计方法的优点在于,这是一种博弈思想,设计者赌你不会修改string,就像键身房通过办了健身卡(拷贝复制)却不去(修改string)的人来赚钱。
string的_Buf数组
vs下string设置了一个大小为16字节的_Buf数组,当字符串长度为15个字节时,存在_Buf数组中,为大于15时,存在_Ptr指针指向的空间中。
因此s1变量的大小16字节的buf数组+8个字节的char*指针+8个字节的size_t size+8个字节的size_t capacity。16+8+8+8=40
tips编译器更早的版本size_t可能为4,当前是vs2020。