>什么是隐式共享类,它们如何工作?
>奇趣科技的Qt网站表示,它可以最大限度地利用资源并最大限度地减少复制.请解释一下这是怎么回事.
>任何人都可以提供任何更好理解的例子吗?任何以任何方式解释这个概念的网站的链接也是受欢迎的.
所有答案的Thanx伙伴们……围绕这个主题的另一个问题是堆栈对象指向堆分配共享数据..这是图…
任何对这个??? …以及究竟什么是引用计数?它是一种计数器,当对象引用公共共享数据时,它是一种反击,反之亦然?
解决方法
string a("hello"); string b = a;
此时你有两个字符串对象a和b,每个对象都有自己的缓冲区来存储一个字符数组.即使缓冲区的内容完全相同,a和b仍然有自己的“hello”副本.这是浪费记忆.如果他们共享缓冲区,则必须使用单个char数组来存储两个字符串的“hello world”.
现在有了QString,它有点不同:
QString a("Hello"); QString b = a;
在这种情况下,只创建一个char数组来存储“hello”. b而不是创建自己的char数组,只会指向一个char数组.这样你就可以节省内存.
现在,如果你执行b [0] =’M’,id est,则修改b,然后b创建自己的char数组,复制数组的内容,然后修改自己的数组.
在Java中,字符串是不可变对象.换句话说,Java没有在String类上提供任何方法来修改其内容.这样做总是可以共享那种数据.
与其他人提到的事情相辅相成:
我怎么知道我可以释放char数组?
这就是“引用计数”的用途.创建对象并将其设置为指向char数组时,其引用计数将增加1,因此它知道有多少对象仍在使用它.当指向它的对象被销毁时,引用计数会递减.当计数器达到零时,char数组知道没有人正在使用它,因此它可以被释放.
这是引用计数的非常粗略的实现.无论如何,我无意准确或正确.我忽略了在C中实现复制构造函数和赋值运算符的正确方法.我无法检查实施是否有效.认为这是一种类似于C的算法描述.我只是想教这个概念.但想象你有这些课程:
class SharedData{ private: int refcount; int data; public: SharedData(int _data){data=_data;refcount=1;} void incRef(){refcount++;} void decRef(){--refcount; if(refCount==0) delete this;} }; class Data{ SharedData* shared; public: Data(int i){shared = new Data(i);} Data(const Data& data){shared = data.shared; shared->incRef();} const Data& operator=(const Data& data){if(shared!=data.shared){ shared->decRef(); shared = data.shared; shared->incRef();} } ~Data(){shared->decRef();} };
类Data的两个对象可以共享同一个SharedData对象,因此:
void someFunction() { Data a(3) //Creates a SharedData instance and set refcount to 1 if (expression) { Data b = a; //b points to the same SharedData than a. refcount is 2 b = Data(4);// b points to diferent SharedData. refcount of SharedData of a is decremented to 1 and b's SharedData has refcount 1 //destructor of b is called. Because shared data of b has now refcount == 0,the sharedData is freed; } //destructor of a is called,refcount is decremented again // because it is zero SharedData is freed }
因此资源使用最大化并且复制最小化. a和b都使用相同的SharedData(aka int 3). . 4没有从a复制到b,他们只是共享相同的数据. int并不是什么大问题,但想象一下,如果SharedData拥有一些大字符串或任何其他更复杂的数据结构.仅复制指针远比几十个字节快.当你真的不需要副本时,它还可以节省大量内存.
什么是写时复制?回想一下我们做b [0] =’M’时所说的话.这是写时复制. b和a共享相同的char数组.但是b需要修改字符串.它无法直接执行,因为它也会修改字符串.所以b必须创建自己的char数组副本才能更改它.因为它只需要在修改数组时创建副本,所以它被称为copy-on-write.