Qt
Неявное совместное использование
Поиск…
замечания
Итераторы стиля STL на контейнере Qt могут иметь некоторый отрицательный побочный эффект из-за неявного обмена. Рекомендуется избегать копирования контейнера Qt, пока у вас есть итераторы, действующие на них.
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!
Основная концепция
Несколько объектов Qt и контейнеров используют неявное совместное использование концепций calles, которое также можно назвать копированием на запись .
Неявный обмен означает, что классы, которые используют эту концепцию, используют одни и те же данные при инициализации.
Одним из этих классов для использования концепции является QString.
QString s1("Hello World");
Это упрощенная модель QString. Внутри он имеет блок памяти, с фактическими строковыми данными и счетчиком ссылок.
QString s2 = s1;
Если мы сейчас скопируем этот QString
оба объекта будут внутренне указывать на один и тот же контент, избегая при этом ненужных операций копирования. Обратите внимание, как количество ссылок также увеличилось. Поэтому, если первая строка удаляется, общие данные все еще знают, что на нее ссылается другая QString
.
s2 += " and all the other Worlds!"
Теперь, когда QString
фактически изменен, объект «отделяется» от блока памяти, копируя его содержимое и изменяя содержимое.