Qtの美しさ(C):暗黙のうちに共有

https://blog.csdn.net/zhu_xz/article/details/6061201

リソースの使用、および最小のデータコピーを最大化するために、Qtは多くのクラスで使用する暗黙的なデータ共有をデータが書き込まれている場合にのみ、コピーされるように、。このメカニズムとしても知られているフライ級モード

私たちは見てみましょうQByteArrayであるかを確認するために、例をどのようにその内部で使用する共有データを追跡するために、データと呼ばれる民間の構造:

図1は、 ストラクトデータ{
 2    QBasicAtomicInt REFを ; // 参照カウンタ、その操作がアトミックである
3。   INT ALLOC; // スペースが割り当て
4。   INTのサイズ; // 実際のサイズのデータ
5。   CHAR *データ; // データを指しポインタ
6。   チャーアレイ[ 1 ]; // データがこの位置に格納することができる
7 }。

データが別の場所に格納されている場合、ここで、データは、データの実際の場所を指すように必要になり、それ自体に記憶されている場合、位置尖っ​​たアレイです。オブジェクトは、データ自体をコピーすることなく、(例えば、代入演算子によって)ポインタのコピーだけをコピーする場合:

1 QByteArray QByteArray ::&演算子 =(CONST QByteArray&OTHER)
 2  {
 3。   // 参照カウンタ値で使用する共有データを増加させる
4。    other.d-> REFREF ();
 5    //は現在の共有データ参照を減少させますカウンタの値
。6    IF(!D-> REF .deref())
 7。     qFree(D);
 8つの   // 共有データ点が使用される
。9    D = other.d;
 10    リターン * この;
 11 }

一方、共有データ(例えばリサイズ()関数によって)変更される場合、それが自動的にコピーされます。

1つの 空隙 QByteArray ::リサイズ(int型のサイズ)
 2  {
 3。   IF(サイズは<= 0 ){
 4。     // ターゲットサイズが正でない場合、空のデータブロックをポイント
5。      データ* X =&shared_empty;
 6      X-> REFREF ();
 7      IF(!D-> REF )(.derefを)
 8。       qFree(D)
 。9      D = X;
 10    } そう IF(D ==&shared_null){
 11。     // これがnullの場合ブロックは、直接、新しい共有データブロックの作成
12     * X = static_castをデータ<データ*>(qMalloc(のsizeof(データ)+ サイズを));
 13である     q_check_ptr(X);
 14      X-> REF = 1 ;
 15      X-> ALLOC = X->サイズ= サイズ;
 16      X - > X-データ=> 配列;
 。17      X->配列[サイズ] = ' / 0 ' ;
 18であるボイド)D-> REF .deref();
 19。      Dは= X;
 20である    } {
 21である     // もし他のオブジェクトは、共有データを使用している、または現在割り当てられているスペースが大きすぎるか小さすぎる
 22      @データをスペースを再割り当て、およびコピー
 23      // 注:共有データブロックでは、この操作は大きな時定数を消費するかもしれない
24      IF(D-> REF!= 。1つの > D-> || ||のallocサイズ(サイズ<D->サイズ&&サイズ<D-> ALLOC >> 1 ))
 25        のrealloc(qAllocMore(サイズはsizeof (データ)));
 26である     IF(D-> ALLOC> = サイズ){
 27        D->サイズ= サイズ;
 28        IF(D-> D-データ==> アレイ){
 29          D->配列[サイズ] = ' / 0 ' 30        }
 31      }
 32    }
 33 }

今度は、使用する方法を見てみましょうQSharedDataQSharedDataPointerをするために、独自の共有データ・オブジェクトを作成します

1  // 最初のデータオブジェクトを作成し、それは参照カウンタの機能を提供するので、QShareDataから継承する必要が
2  クラス SharedDataを:パブリックQSharedData
 3。 {
 4  公共5    SharedData()
 。6      :QSharedData()
 7。 VAR0 8。   { }
 。9    SharedData(CONST SharedData&OTHER)
 10      :QSharedData(OTHER)
 。11VAR(他のVAR 12である   {}
 13は、   int型の VAR ;
 14 };
 15  //は、オペレータの作成
16  クラスをDataOwner、
 17。 {
 18は 公衆19    DataOwner、()
 20がある    :D(新しい新しいSharedData)
 21は、   {}
 22れる    DataOwner、(int型 VAR 23がある    :D(新しい新しいSharedData)
 24    {
 25      // 書き込み操作、オペレータのために- >自動的に共有データのコピーを必要なときに
26ある      D-> VAR = VAR ;
 27    }
 28  プライベート29    //QSharedDataPointerテンプレートクラスが暗黙的に共有の実装の詳細を隠し、コピーコンストラクタと代入演算子を作成する必要はありません
30    QSharedDataPointer <SharedData> ; Dが
 31です }。

今、非常にシンプル!まあ、興味を持っている友人ができQExplicitlySharedDataPointer);明示的なデータ共有を作成します

 

おすすめ

転載: www.cnblogs.com/Vancamel/p/11346237.html