ディープコピー対浅いクラスとオブジェクト

 構造とクラスの違いは以下のとおりです。別のデフォルトのアクセスレベル
クラスの使用に注意してください:
•として秘密鍵と公開鍵の2回のクラス宣言は、任意の順序で表示されることがあります。プログラムをより明確にするためには、パブリックとプライベートのメンバーのすべてのメンバーが一緒に分類しました
•プライベートとパブリックのほか、保護された(保護部材)に加え、キーワード
•データメンバーは、任意のデータ型を使用できますが、自動を使用することはできません、登録またはEXTERN説明
•あなたは、クラス宣言でデータメンバを初期化することはできません
 
op.setPoint(1,2)は、実際op.point ::設定値(1,2)の省略形で、等価的に、
•外部関数は、プライベートメンバーオブジェクトを参照することはできません。
 
コンストラクタとデストラクタ
コンストラクタ
条件のコンストラクタの呼び出し
1.直接呼び出すオブジェクトを定義します。
  複合体A(1.1,2.2)。
宇宙物体の2動的割り当て
  COMPLEX * pを=新しいコンプレックス(3.0,4.0);
3.(名前のないオブジェクト)無名のオブジェクトを定義します。
  複合体(2,4)。
  新しいコンプレックス(4,8);
デフォルトのパラメータを持つコンストラクタであってもよいです、
コンストラクタは、さまざまな状況に適応するために、オーバーロードすることができます。
注意:オーバーロードされたコンストラクタの両方でクラスを、デフォルトのパラメータがあります
コンストラクタ、曖昧製造することが可能です
デストラクタ
典型的には、オブジェクトに割り当てられたメモリ空間の解放などのいくつかのクリーンアップタスクを実行するために使用されるコンストラクタと逆の動作を行う特別なデストラクタメンバ関数も
デストラクタは、次の機能があります。
•同じコンストラクタデストラクタ名は、それがチルダ(〜)の前に追加する必要があります
•デストラクタはパラメータや戻り値なしと一つのクラスで、上書きすることはできませんが、デストラクタを持つことはできません
•オブジェクトを取り消した場合、コンパイラが自動的にデストラクタを呼び出します
条件は、デストラクタを呼び出します
1.オブジェクトを自動的ライフサイクルを終了します
たとえば、次のようにグローバルオブジェクト、ローカルオブジェクト
  {錯体A(1.1,2.2);}
  ボイド楽しい(複素P){}。
2.プログラマ手動解除オブジェクトポインタ
  COMPLEX * pを=新しいコンプレックス(5,6);
  Pを削除します。
同じスコープ内のクラスオブジェクトの実行順序コンストラクタとデストラクタ:第一の構成デストラクタ
 
コピーコンストラクタ
コピーコンストラクタは特殊なコンストラクタです。
すでに存在しているオブジェクトに基づいて新しいオブジェクトを作成するために使用されます。典型的には、オブジェクトがで新しく作成されたオブジェクトにコピーされるドメインパラメータによって表されます
各クラスは、ユーザーが自分のニーズを定義することができますコンストラクタを持っている、またはシステムは、クラスのデフォルトのコピーコンストラクタを生成することができ
コピーコンストラクタ呼び出し条件
1.オブジェクトを定義
  点p1(30,40)。
  点P2(P1); //ポイントP2 = P1;
2.オブジェクト関数のパラメータ
  空の試験(点P);
  試験(P1)。
3.戻り値は、オブジェクトの関数であります
  点試験()。
  テスト();
 
ヒント:無名のオブジェクトシステムを使用してオブジェクトを初期化するために、コピーコンストラクタを呼び出すことはありません。コンストラクタを呼び出します
例えば:
点A =点(4,5)。
点試験(点P){retrunのP;} 
テスト(ポイント(4,5))
 
構造派生クラスは、基本クラスのコンストラクタは、部材は、建設順序オブジェクト。
基底クラスのコンストラクタ=「メンバーは、建設順序オブジェクト=」派生クラスのコンストラクタ
書式#include <iostreamの>
書式#include <文字列>
名前空間stdを使用。
クラスサード{
パブリック:
    三番() {
        裁判所未満<< "第三のコンストラクタ" <<てendl;
    }
}。
 
クラスBase {
パブリック:
    ベース(文字列名){
        裁判所未満<< "基本コンストラクタ" <<てendl;
        this->名前=名前;
    }
    ボイドDISP1(){
        coutの<< this->名<<てendl;
    }
プライベート:
    文字列名。
}。
 
派生クラス:公共ベース{
パブリック:
    派生(文字列名、int型の年齢):ベース(名前)、第三(新三()){
    //第三(新三())、ベース(名前)と同じ結果を書きました
        裁判所未満<< "derviedコンストラクタ" <<てendl;
        this->年齢=年齢;
    }
    ボイドDISP2(){
        coutの<< this->年齢<<てendl;
    }
プライベート:
    int型の年齢;
    第三*;
}。
 
メインint型()
{
    誘導されたD( "zhangsan"、10);
    d.disp1();
    d.disp2();
    0を返します。
}
 
結果:
ベースのビルダー
第三のコンストラクタ
derviedビルダー
zhangsan
10
 
修飾されたconstメンバ関数
任意のメンバ関数は、クラス内の任意のデータメンバにアクセスすることができますが、我々はそれがデータメンバーを変更させたくないとき、私たちは、修正クラスのメンバ関数のconstを使用することができますので、
クラスCLASS_NAME {
プライベート:
......
パブリック:
(タイプ)FUNCTION_NAME(...)のconst {
}
}。
constメンバ関数によって変更するとき、in vivoでのメンバ関数は、ボディ構造のデータメンバーのいずれかを変更しなくてもよいです
しかし、例外前場合がある可変データ修正上型のメンバは、変更されたデータメンバーのin vivoでのconstメンバ関数を変更することができる場合に
 
オブジェクトの割り当て
書式#include <iostreamの>
std :: cinをを使用しました。
std :: coutのを使用して、
std :: ENDLを使用して、
MyClassクラス{
プライベート:
    、B int型。
    char * P;
パブリック:
    空のセット(INT I、int型J){
        = I;
        B = J;
    }
    ボイドショー(){
        coutの<< << '' << B <<てendl;
    }
   //〜MyClassの(){
    // Pを削除します。
    //}
}。
 
メインint型()
{
    MyClassのP1;
    MyClassのP2;
    p1.set(20,5)。
    P2 = P1; //割当対象
    p2.set(10、1)。
    p1.show(); // 20,5
    p2.show(); // 10,1
    0を返します。
}
 
説明:
  割り当てのターゲットオブジェクトを割り当てるために、2つのオブジェクトがそのようなオブジェクトの異なるタイプと同じタイプでなければならない1、
     コンパイル時エラー。
  図2に示すように、2つのオブジェクト間の割り当て、唯一同じメンバーとそれらのデータオブジェクト、および2つのオブジェクトが別々のままであるように。例えば
     本実施形態のオブジェクトの後、そしてp2.set P2の設定値を呼び出し、それがP1の値には影響を与えません。
  図3に示すように、オブジェクトは、既定の代入演算子の機能を割り当てることによって達成されます。
  オブジェクトが他のオブジェクトの値が割り当てられている場合4、ほとんどの場合において成功しているが、ポインタクラスの存在下で、よいです
     これは、エラーが発生します。
 
浅い対深いコピー
浅いコピーのデフォルトのコピーコンストラクタのための
シャローコピー:ビットコピー、コピーコンストラクタ、代入のオーバーロード
複数のオブジェクトが同一のリソース、複数のクラッシュやメモリリークとリソース解放を共有します
ディープコピー:一緒に独自のリソースを持つ各オブジェクトは、我々は明示的にコピーコンストラクタと代入演算子を提供する必要があります。
コピー間の差のシェード:
    浅いコピーである 新しいオブジェクトに元のオブジェクトのデータ・タイプ・フィールドのコピー にコピーされ、新しいオブジェクトにコピーされた参照型フィールド「参照」ではなく、「参照物体」 、その結果、元のオブジェクトと新しいオブジェクト参照新しいオブジェクト参照タイプフィールドが変更同じオブジェクトが、元のオブジェクトの対応するフィールドにつながる変更されます。
    ディープコピーは、基準の面で異なっている、それは同じフィールド新しい、オリジナルのコンテンツ分野の深いコピーを作成することです、データの二枚ほどの大きさであるので、2つの参照は、参照で、新しいオブジェクトタイプ異なっていますフィールドが変更され、元のオブジェクトは、磁界の変化が発生することはありません。
書式#include <iostreamの>
書式#include <string.hの>
名前空間stdを使用。
クラス学生{
パブリック:
    学生(のchar *名、int型の年齢):年齢(歳){
        this->名=新しいCHAR [strlenを(名)+ 1]。
        strcpyの(this->名、名);
    }
    ボイドDISP(){
        coutの<<名<<てendl;
        coutの<<年齢<<てendl;
    }
    無効setAge(int型の年齢){
        this->年齢=年齢;
    }
    ボイドdeleteName(){
        名前を削除します。
    }
プライベート:
    CHAR *名前。
    int型の年齢;
}。
メインint型()
{
    学生STU1( "zhangsan"、1);
    学生STU2 = STU1。
    stu2.setAge(2)。
    stu1.disp(); // zhangsan 1
    stu2.disp(); // zhangsan 2
    stu1.deleteName(); //名前の参照を削除
    stu2.disp(); // "" 2
    0を返します。
}
 
解決策:自分自身のコピーコンストラクタを達成するために
学生(CONST学生&STU){
        this->名=新しいCHAR [STRLEN(stu.name)+ 1]。
        strcpyの(this->名、stu.name)。
}
コピーコンストラクタを使用して、クラスのデータメンバ内のポインタは、そこにあるのはいつですか?
明示的にコピーコンストラクタを宣言されていない場合、コンパイラはデフォルトのコピーコンストラクタを生成し、一般的なケースでの実行も良いです。押圧部材は、同一のメモリを指す2つの異なるポインタをもたらすコピーコンストラクタ、(例えばPTR1 = PTR2)であるため、デフォルトコピーコンストラクタ:しかし、問題は、イベント・クラスは、データメンバへのポインタを有するで生じます。デストラクタ無料(PTR1)を呼び出して、破壊されたインスタンスは、このメモリを解放すると、残りのインスタンスPTR2ポインタが無効であるかなりある、破壊されたときに自由(PTR2)、エラーが発生します二回のメモリのブロックを解放するために繰り返します。この状況は、明示的に宣言し、新しいインスタンスへの新しいポインタにメモリを割り当てるために、自分自身のコピーコンストラクタを実装する必要があります。        
 
コピーコンストラクタは、プライベートメンバ変数にそれを呼び出すことができますか?
ANSWER:雛子我々はコピーコンストラクタがその時の特別なコンストラクタ、クラスのメンバ変数やその動作なので、無制限のプライベートなときにことを知っています。
 
コピーコンストラクタで次の関数、なぜ?オーバーロード可能
X :: X(のconst X&); //コピーコンストラクタ
X :: X(X);
X :: X(X&、int型A = 1); //コピーコンストラクタ
X :: X(X&、int型A = 1、INT B = 2); //コンストラクタをコピーします
クラスXの場合、コンストラクタの最初の引数は、次のいずれかの場合:ソリューション:
   a)のX&
   B)のconst X&
   C)揮発性X&
   D)constは揮発性X&
  そして、これはコピーコンストラクタ関数です。
 
クラスは1つのコピーコンストラクタ関数より以上であってもよいですか?
   回答:複数のクラスのコピーコンストラクタがあるかもしれません。
クラスX {
パブリック:
  X(のconst X&); // constのコピーコンストラクタ
  X(X&); //非constコピーコンストラクタ
}。
唯一の1つのパラメータがあり、クラスがX&コンストラクタをコピーしている場合は、そのオブジェクトが使用されるか、または揮発性X用のconst Xのコピーの初期化実装することができないことに注意してください。
クラスはコピーコンストラクタを定義しない場合は、コンパイラが自動的にデフォルトのコピーコンストラクタを生成します。
このデフォルトのパラメータは、コンテキストを決定するためによると、コンパイラによって、X :: X(のconst X&)またはX :: X(X&)であってもよいです。
 
コピーコンストラクタ関数は、テンプレートメンバーによって生成することができません。
構造体X {   
    テンプレート<型名T>   
    X(CONST T&)。// CTORをコピーしないで、TはXすることはできません   
  
    テンプレート<型名T>   
    演算子=(定数T&)。// ass'tをコピーしないで、TはXすることはできません   
}。   
メンバーは、テンプレートを機能しませんので、理由は単純で、テンプレートのメンバ関数は、言語のルール、およびプログラムは、コピーコンストラクタを必要とし、あなたがそれを宣言しない場合、コンパイラが自動的にあなたのための1つを生成することを言語のルールを変更しません。代入演算子のオーバーロードは、同じルールに従う、コンパイラはコピーコンストラクタを生成防ぎます。
 
問題を解決するカッティング:
書式#include <iostreamの>
書式#include <string.hの>
名前空間stdを使用。
 
クラスBase {
パブリック:
    仮想ボイドDISP(){
        裁判所未満<< "ベース:: DISP" <<てendl;
    }
}。
クラスDervied:公共ベース{
パブリック:
     仮想ボイドDISP(){
        裁判所未満<< "Dervied :: DISP" <<てendl;
    }
}。
無効印刷(ベースB)//ベース&B OK参照を変更
{
    裁判所未満<< "印刷" <<てendl;
    b.disp();
}
(int型ARGC、チャー*のARGV [])INT主
{
    Dervied D;
    プリント(D)。//プリントベース:: DISP
    0を返します。
}
 

おすすめ

転載: www.cnblogs.com/gschain/p/11244960.html