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-> REF。REF (); 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-> REF。REF (); 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 }
今度は、使用する方法を見てみましょうQSharedDataとQSharedDataPointerをするために、独自の共有データ・オブジェクトを作成します。
1 // 最初のデータオブジェクトを作成し、それは参照カウンタの機能を提供するので、QShareDataから継承する必要が 2 クラス SharedDataを:パブリックQSharedData 3。 { 4 公共: 5 SharedData() 。6 :QSharedData() 7。 、VAR(0 ) 8。 { } 。9 SharedData(CONST SharedData&OTHER) 10 :QSharedData(OTHER) 。11 、VAR(他の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);明示的なデータ共有を作成します