6.4.5. ジェネレータをコピーし、入力演算子をコピーします.

4274 ワード

浅い層放射をもたらす暗黙放射生成子と放射対入演算子。


ソースコード



->暗黙的レプリケーションジェネレータのため、pAが指す位置はBが指す位置のメモリと同じです.
削除がdelete pAの場合、同じメモリを指すBの参照値は空になります.
私たちはトラブルに遭った.
これを浅い放射線と言います.
これらの問題を解決するには、開発者がレプリケーションジェネレータを明確に作成する必要があります.

6.4.6オブジェクト値によって呼び出される


: CObject a(b), CObject a = b; レプリケーション作成者を呼び出す
このようにして2回発生した場合を確認する.
しかし、もう一つあります.
すぐに!オブジェクトの値呼び出し.
void func(CObject a)
{
}
->レプリケーション作成者ではなく、レプリケーション作成者を呼び出します.
したがって、関数が終了すると、領域値になるため、消滅者も呼び出されます.
コストがかかるため、オブジェクトをパラメータとして送信するときに参照を使用することをお勧めします.
いいえ、パラメータとしてパラメータを使用する必要があります.

  • パラメータの値としてオブジェクトを使用する場合.


  • ReferenStarに直接言わせて

    ->不要なオブジェクトの生成を禁止します.
    =>パラメータとして入力した値が変更されないようにconstを追加する必要があります!
  • 分かった点。

  • レポートタイプとバリュータイプはオーバーロードできますか?

    ->ファジイが発生します.
  • レプリケーションジェネレータはいつ呼び出されますか?


  • 初期化時にカッコで別のオブジェクトを囲み、
  • オブジェクトを宣言します.
  • オブジェクトを宣言しながら他のオブジェクトを置換する場合、
  • 関数のパラメータとしてオブジェクトを使用する場合、
  • 関数の一時オブジェクトを返す場合.
  • 6.2.7コピーの防止方法


  • レプリケーションジェネレータと代入演算子を
  • クラスの公衆に宣言する方法がある.
    ->リンクエラーが発生します.
  • クラスのprivateでレプリケーションジェネレータと代入演算子を宣言します.
    ->コンパイルエラーが発生します.
    //リンクエラーよりもコンパイルエラーの方が良いです.
  • noncopyableクラスを使用します.
    :継承後、コピーする場合は、親もコピーする必要があります.親のコピー作成を制御することで、
    止められる
    この絵のようです.Protectedを使用するのは、非copyableクラスとは独立しているためです.
    使わないためです.
  • 6.2.8 RValue Referenceの使用


    明示的に作成されたレプリケーションジェネレータによって効率が低下する場合があります。


    :関数内のオブジェクトを直接返す場合は、レプリケーションジェネレータが呼び出されます.
    すでに消去するオブジェクトを返すと、コピー作成者は別のオブジェクトのメモリを作成し、消去するオブジェクトのメモリの削除を阻止します.
    オブジェクトを受信して使用すると、かえってメモリを節約できます.
    なんだよ.どうやって?rValue参照を使用すればよい.

  • レプリケーション・ジェネレータによって2回のメモリを生成するコード



  • RvalueReferenceでメモリのコードを回収

    :rValueリファレンスのみを使用してメモリ割り当てを行います.
  • ソースコード

    #include <iostream>
    using namespace std;
    
    class CText
    {
    public :
    	CText(const char *Text)
    	{
    		cout << "constructor " << endl;
    		mLen = strlen(Text);
    		mText = new char[mLen + 1];
    		strcpy(mText, Text);
    	}
    	CText(const CText& obj)
    	{
    		cout << "copy constructor " << endl;
    		mText = new char[obj.mLen + 1];
    		cout << "memory allocation " << endl;
    		strcpy(mText, obj.mText);
    		mLen = obj.mLen;
    	}
    	CText(CText&& obj)
    	{
    		cout << "move constructor " << endl;
    		mText = obj.mText;
    		mLen = obj.mLen;
    
    		obj.mText = nullptr;
    		obj.mLen = 0;
    	}
    
    	~CText() {
    		cout << " destructor " << endl;
    		if (mText)
    		{
    			cout << "memory delete " << endl;
    			delete[] mText;
    			mLen = 0;
    		}
    	}
     
    	char *mText;
    	int mLen;
    };
    
    CText GetText()
    {
    	CText temp("hi world");
    	return temp;
    }
    
    int main()
    {
    	CText t1 = GetText();
    }

    分かった点。


    一時オブジェクトを返すと、レプリカを作成してメモリが生成されます.
    rValueリファレンスを使用して防止!

    6.4.9等価演算子。


    :基本タイプでは、同じメモリサイズまたはビットステータスを比較しません.比較価格です.

    :doubleとintはメモリ構造が異なりますが、値が同じなので、出力が同じと判断できます.

    クラスで違います。


    :複数の代入演算子を定義できるためです.
  • クラスでは、ピア演算がオーバーロードされていることがわかります.

    =>したがって、そのタイプに応じてオーバーロード関数を作成する必要があります.