Qt красота (C): неявное совместное использование

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 создать совместные явные данные;)

 

рекомендация

отwww.cnblogs.com/Vancamel/p/11346237.html