Qt
Impliciet delen
Zoeken…
Opmerkingen
STL-stijl iterators op Qt Container kunnen een negatief neveneffect hebben als gevolg van impliciet delen. Het wordt geadviseerd om geen Qt-container te kopiëren terwijl iterators erop actief zijn.
QVector<int> a,b; //2 vectors
a.resize(1000);
b = a; // b and a now point to the same memory internally
auto iter = a.begin(); //iter also points to the same memory a and b do
a[4] = 1; //a creates a new copy and points to different memory.
//Warning 1: b and iter point sill to the same even if iter was "a.begin()"
b.clear(); //delete b-memory
//Warning 2: iter only holds a pointer to the memory but does not increase ref-count.
// so now the memory iter points to is invalid. UB!
Basis concept
Verschillende Qt-objecten en -containers gebruiken een concept dat impliciet delen aanroept, waarnaar ook kan worden verwezen als copy-on-write .
Impliciet delen betekent dat de klassen die dit concept gebruiken dezelfde gegevens delen bij de initialisatie.
Een van deze klassen om het concept te gebruiken is QString.
QString s1("Hello World");
Dit is een vereenvoudigd model van een QString. Intern heeft het een geheugenblok, met de actuele stringgegevens en een referentieteller.
QString s2 = s1;
Als we nu kopieert deze QString
beide objecten wordt intern naar dezelfde inhoud, zodat onnodig kopie operaties te voorkomen. Merk op hoe het aantal referenties ook werd verhoogd. Dus in het geval dat de eerste string wordt verwijderd, weten de gedeelde gegevens nog steeds dat er naar wordt verwezen door een andere QString
.
s2 += " and all the other Worlds!"
Wanneer de QString
daadwerkelijk wordt gewijzigd, "ontkoppelt" het object zichzelf van het geheugenblok, kopieert het de inhoud en wijzigt het de inhoud.