【C++Primer】コピー制御

2830 ワード

十三、複製制御
1.コンストラクタのコピー
クラスのメンバー関数は、inlineタイプを黙認します.したがって,クラス定義内の関数宣言表示をinlineタイプとして定義しても,関数定義を行う際にinlineを省略することができる.
//レプリケーションコンストラクション関数は定数参照タイプである必要があります.値伝達パラメータに同意すると、無限ループ呼び出しが発生し、メモリオーバーフローが発生すると仮定します.
 CopyConstruct(const CopyConstruct& a){value = a.value;}
複製コンストラクション関数はvectorsvec(5)のようなシーケンスコンテナ内の要素を初期化するために使用することができ、このような方法ではデフォルトコンストラクション関数と複製コンストラクション関数が使用される.
コンパイラはまずstringのデフォルトのコンストラクタを使用してsvecを初期化する一時値を作成し、レプリケーションコンストラクタを使用してsvecの各要素に一時値をコピーします.
配列メンバーは例外で、クラスに配列メンバーがあると仮定します.合成レプリケーション構造関数は配列をレプリケーションし、配列の各要素をレプリケーションします.注意ポインタは文字値のみをコピーします.レプリケーションコンストラクション関数は、このタイプのオブジェクトを関数に渡し、関数からクラスオブジェクトを返すときに暗黙的に呼び出されます.したがって、レプリケーションコンストラクション関数をexplicitとして指定するべきではありません.クラスタイプまたは組み込みタイプ(ポインタタイプは含まれませんが)のみを含むクラスは、複製構造関数を明示的に定義する必要はありません.
クラスにポインタタイプまたはコンストラクション関数に割り当てられたメンバーの他のリソースがある場合は、レプリケーションコンストラクション関数を定義する必要があります.
一部のクラスではiostreamクラスなどのレプリケーションを完全に禁止する必要があります.レプリケーションを禁止するには、クラスがレプリケーション構造関数をprivateとして明示的に宣言する必要があります.
コンパイラは、レプリケーションの試みにかかわらず、ユーザーコードを拒否します.
しかしこの場合,友元やクラスのメンバにおいても複製が可能である.それらも禁止したいと仮定し、privateレプリケーション構造関数を宣言できますが、定義が正しくありません.注意は定義です.空のレプリケーション構造関数として定義するのではなく、メンバー関数を定義せずに宣言するのは合法です.しかし、メンバー関数を定義していない試行は、リンクに失敗します.privateのレプリケーションコンストラクタを宣言すると、ユーザーコードがクラスタイプオブジェクトをレプリケーションしようとする試みにかかわらず、構文エラーが発生します.友元関数とメンバー関数の呼び出しにより、リンクエラーが発生します.
レプリケーションコンストラクタが定義されていると仮定すると、コンパイラはデフォルトコンストラクタを合成しません.
2.代入オペレータ
クラスが独自の割り当てオペレータを定義していないと仮定すると、コンパイラは1つを合成します.割り当てオペレータの戻りタイプは、左/右のオペランドへの参照を返します.割り当てオペレータ関数はクラスのメンバー関数でなければなりません.割り当て値はクラスのメンバーでなければなりません.パラメータリストの最初のパラメータはthisポインタであり、省略されています.合成賦値オペレータ関数は、合成レプリケーション構造関数と同様に、メンバーごとの賦値も実行されます.
一般に、クラスはレプリケーション構造関数を定義する必要があると仮定します.割り当てオペレータも必要です.
3.構造関数
動的に割り当てられたオブジェクトは、そのオブジェクトのポインタが削除された場合にのみ取り消されます.
動的割り当てオブジェクトの参照またはポインタが役割ドメインを超えている場合、構造関数は実行されません.
構造関数は、明示的にdeleteを呼び出すだけで呼び出されます.ただし、プロセスが終了すると取り消されます.
クラスが構造関数を解析する必要があると仮定すると、割り当てオペレータと複製構造関数も必要です.これは3つの法則と呼ばれます.
コンパイラは、オブジェクトが作成されたときの逆順序でstatic以外のメンバーを取り消す構造関数を合成します.
クラス・タイプのメンバーの場合、合成構造関数は、そのメンバーの構造関数を呼び出してオブジェクトを取り消します.
コンストラクション関数を合成しても、ポインタメンバーが指すオブジェクトは削除されません.したがって、一般的には、リソースを解放するために独自の構造関数を定義します.
構造関数とレプリケーション構造関数または付与演算子の重要な違いは、独自の構造関数を記述しても、合成構造関数が実行されることです.構造関数は1つしかありません.
注:ここでは実行を使用します.合成コンストラクション関数は、メンバーを取り消すためにクラスタイプのコンストラクション関数として呼び出されます.
4.ポインタメンバーの管理
ほとんどのC++クラスでは、次の3つの方法のいずれかの管理ポインタメンバーが使用されます.
1:ポインタメンバーは通常のポインタ型の動作を行います.処理しない.
2:スマートポインタを使用します.参照カウントを使用して、貢献オブジェクトを管理します.
     class U_Ptr {
         friend class HasPtr;
         int *ip;
         size_t use;
         U_Ptr(int *p): ip(p), use(1) { }
         ~U_Ptr() { delete ip; }
     };

3:オブジェクトを指すのは1つだけです.各オブジェクトには独自のコピーがあります.
本文のブログのオリジナルの文章、ブログ、同意を得ないで、転載してはいけません.