什么是隐式共享类?

rot*_*age 6 c++ oop qt memory-management qt4

在过去的6个月里,我一直在与Qt合作,我仍在努力理解隐式共享课程的概念.我有以下问题:

  1. 什么是隐式共享类以及它们如何工作?
  2. 奇趣科技的Qt网站表示,它可以最大限度地利用资源并最大限度地减少复制.请解释一下这是怎么回事.
  3. 任何人都可以提供更好的理解的例子吗?任何以任何方式解释这个概念的网站的链接也是受欢迎的.

所有答案的Thanx伙伴们......围绕这个主题的另一个问题是堆栈对象指向堆分配共享数据..这是图...这个图片..

任何对这个??? ...以及究竟什么是引用计数?它是一种计数器,当对象引用公共共享数据时,它是一种反击,反之亦然?

And*_*ani 14

想象一下跟随.你正在使用C++ 03,你写道:

string a("hello");
string b = a; 
Run Code Online (Sandbox Code Playgroud)

此时你有两个字符串对象a,b每个对象都有自己的缓冲区来存储一个字符数组.即使缓冲区的内容是完全一样的,a而且b还是有自己的"你好"的副本.这是浪费记忆.如果他们共享缓冲区,则必须使用单个char数组来存储两个字符串的"hello world".

现在有了QString,它有点不同:

QString a("Hello");
QString b = a;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,只a创建一个char数组来存储"hello".b而不是创建自己的char数组,将简单地指向a的char数组.这样你就可以节省内存.

现在,如果你这样做b[0]='M',你修改b,然后b创建自己的char数组,复制数组的内容,a然后修改自己的数组.

在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();}
};
Run Code Online (Sandbox Code Playgroud)

类的两个对象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
}
Run Code Online (Sandbox Code Playgroud)

因此资源使用最大化并且复制最小化.双方ab使用相同的SharedData(又名INT 3)..该4不是从拷贝ab,他们只是共享相同的数据.int并不是什么大问题,但想象一下如果SharedData持有一些大字符串或任何其他更复杂的数据结构.仅复制指针远比几十个字节快.当你真的不需要副本时,它还可以节省大量内存.

什么是写时复制?
回想一下上面我说的话b[0]='M'.这是复制.ba共享相同的char数组.但b需要修改字符串.它无法直接执行,因为这也会修改字符串a.因此b必须创建自己的char数组副本才能更改它.因为它只需要在修改数组时创建副本,所以它被称为copy-on-write.