What are implicitly shared classes?

I have been working with Qt for the past 6 months, and I'm still trying to understand the concept of implicitly shared classes . I have the following questions:

  • What are implicitly shared classes and how do they work?
  • Trolltech Qt says it maximizes resource usage and minimizes copying. Please explain to me how this happens.
  • Can someone give an example for a better understanding? A link to any site explaining this concept using or using an example is also welcome.

Thanx guys for all the answers .. I came up with another question regarding this question - stack objects point to a bunch of highlighted shared data .. this is a diagram ... this image ..

Does anyone accept this ??? ... and what exactly is a link counter? This is a kind of crash counter when objects refer to common, shared data ... and vice versa?

+6
source share
3 answers

Imagine the following. You use C ++ 03 and you write:

string a("hello"); string b = a; 

At this point, you have two lines of objects a and b , and each of them has its own buffer for storing an array of characters. Although the contents of the buffers are exactly the same, a and b still have their own copy of hello. This is a waste of memory. If they share a buffer, you will have to use a single char array to store "hello world" for both lines.

Now with QString this is a little different:

 QString a("Hello"); QString b = a; 

In this case, only a created a char array to store hello. b instead of creating its own char array, it just points to a char array. This way you save memory.

Now, if you execute b[0]='M' , id est, you modify b , then b creates its own char array, copying the contents of the array a , and then modifying its own array.

In Java, strings are immutable objects. In other words, Java does not provide any methods in the String class to modify its contents. This is done so that you can always transfer this kind of data.

In addition to things mentioned by others:

How to find out that I can free a char array?
To do this, use the "account". When an object is created and configured to point to a char array, its reference count will be incremented by 1, so it knows how many objects are still using it. When the object that points to it is destroyed, the reference count is reduced. When the counter reaches zero, the char array knows that no one is using it, so it can be freed.

This is a very crude implementation of reference counting. I do not intend to be exact or correct in any case. I ignore the correct ways to implement copy constructors and assignment operators in C ++. I cannot check if the implementation is working. Think of it as a description of an algorithm similar to C ++. I just want to teach concepts. But imagine that you have these classes:

 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();} }; 

Two objects of the Data class can share the same SharedData object, therefore:

 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 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 } 

In this way, resource utilization was maximized and the copy was minimized. Both a and b used the same SharedData (aka int 3 )., 4 not copied from a to b , they just shared the same data. Int doesn't really matter, but imagine if SharedData contained some sort of large string or any other more complex data structure. Copying just a pointer is much faster than dozens of bytes. And it also saves a lot of memory when you really don't need a copy.

What is copy-on-write?
Recall above what I said when we did b[0]='M' . It was copying to record. b and a used the same char array. But b needs to change the line. He could not do this directly, because that would also change the line for a . Therefore, b must create its own copy of the char array in order to be able to modify it. Since it should only create a copy when it changes the array, it is called copy-on-write.

+13
source

Based on my reading of http://doc.qt.io/archives/qt-4.7/implicit-sharing.html ...

This is basically just a common name for any class that uses reference counting and copy-on-write to avoid unnecessarily copying class-driven data.

reference counting

Reference counting is a method that ensures that an object hangs as long as someone is interested in it. Any piece of code that wants to hold an object for a certain period of time increases the reference count. When it loses interest in an object, it decreases the link, and if the reference count goes to zero, which means that it was the last interested party, it also destroys the object.

In the case of general Qt classes, it seems that reference counting is completely automatic. Links are managed through the constructors and destructors of the classes in question.

Copy on recording

In addition to sharing through reference counting, classes can ensure that different parties do not compress each other's versions of an object by making a copy of the underlying data immediately before making any changes to it. This is called copy to write, or COW, an idiom.

+2
source

Source: https://habr.com/ru/post/924383/


All Articles