https://blog.csdn.net/zhu_xz/article/details/6061201
Для максимально эффективного использования ресурсов, а также минимум копирования данных, то Qt использует во многих классах неявного обмена данных , так что данные копируются только тогда , когда записываются. Этот механизм также известен как режим мухи .
Возьмем QByteArray пример, чтобы увидеть , что как . Его внутреннее использование частная структура под названием Data , чтобы отслеживать общие данные:
. 1 STRUCT в данных { 2 QBasicAtomicInt REF ; // счетчик ссылок, его работа атомный 3. INT в Alloc; // пространство , выделенное 4. INT размер; // данные фактического размера 5. Символ * Данные; // указывает на данные указатель . 6 символ Массив [ 1. ]; // данные могут быть сохранены в этом положении 7 };
При этом, если данные хранятся в другом месте, данные нужно будет указать на фактическое расположение данных, если они хранятся в себе, этом месте заостренный массив. Когда объект копируется (например, с помощью оператора присваивания), единственный экземпляр указателя, без копирования самих данных:
. 1 QByteArray QByteArray :: & оператор = ( Const QByteArray & ДРУГОЙ) 2 { 3. // увеличить общие данные , которые будут использоваться в значении счетчика ссылок 4. Other.d-> REF . REF (); . 5 // снижает текущую ссылку на общие данные значение счетчика . 6 ЕСЛИ (! D-> REF .deref ()) 7. qFree (D); . 8 // общие точки данных , которые будут использоваться . 9 D = other.d; 10 возврата * этого ; . 11 }
С другой стороны, если общие данные, которые будут модифицированы (например, путем изменения размера () функция), он автоматически копируется:
. 1 аннулированию в QByteArray :: изменения размера ( INT размер) 2 { 3. ЕСЛИ (размер <= 0 ) { 4. // Если целевой размер не является положительным, то указывает на пустой блок данных 5. Данных * Х = & shared_empty; . 6 Х-> REF . REF (); 7 . ЕСЛИ (D->! REF .deref ()) 8. qFree (D); . 9 D = Х; 10 } еще ЕСЛИ (D == & shared_null) { . 11 // Если это нулевое блок, непосредственно создать блок новые общие данные 12 * Х = static_cast в данных <Data *> (qMalloc ( в SizeOf (данные) + размер)); 13 является q_check_ptr (Х); 14 Х-> REF = . 1 ; 15 Х-> The Alloc = Х-> размер = размер; 16 Х -> X-Data => Массив; . 17 Х-> Массив [размер] = ' / 0 ' ; 18 ( аннулируются ) D-> REF .deref (); 19. D = Х; 20 } еще { 21 // , если другие объекты , используя общие данные, или распределенный в настоящее время пространство слишком велик или слишком мал 22 @Переназначение пространства и скопировать данные 23 // Примечания: эта операция в общих блоках данных может потреблять большое постоянное время 24 IF (D-> REF ! = . 1 || размер> D-> || Alloc ( размер <D-> размер && размер <D-> в Alloc >> 1. )) 25 перераспределить (qAllocMore (размер, SizeOf (данные))); 26 ПЧ (D-> The Alloc> = размер) { 27 D-> размер = размер; 28 ПЧ (D-> D - данных ==> Массив) { 29 D-> Массив [размер] = ' / 0 ' ; 30 } 31 } 32 } 33 }
Теперь давайте посмотрим, как использовать QSharedData и QSharedDataPointer , чтобы создавать свои собственные общие объекты данных .
1 // Сначала создаем объект данных, вы должны наследовать от QShareData, так как она обеспечивает функциональность счетчик ссылок 2 класса SharedData: общественный QSharedData . 3 { 4. Общественность : . 5 SharedData () 6. : QSharedData () . 7 , вар ( 0 ) . 8 { } 9. SharedData ( Const SharedData & ДРУГОЙ) 10 : QSharedData (ДРУГОЙ) . 11 , вар (. ДРУГОЙ вар ) 12 {} 13 INT вар ; 14 }; 15 // затем создать оператор 16 класса DataOwner, . 17 { 18 общественных : . 19 DataOwner, () 20 : D ( новый новый SharedData) 21 {} 22 DataOwner, ( INT вар ) 23 : D ( новый новый SharedData) 24 { 25 // для операций записи, оператор -> копия общих данных автоматически при необходимости 26 является D-> вар = вар ; 27 } 28 Частное : 29 //QSharedDataPointer шаблонный класс скрывает детали реализации совместно неявно, не нужно , чтобы создать конструктор копирования и оператор присваивания 30 QSharedDataPointer <SharedData> D; 31 };
Довольно просто, прямо сейчас! Ну, друзья , которые заинтересованы могут QExplicitlySharedDataPointer создать совместные явные данные;)