6.4.5. ジェネレータをコピーし、入力演算子をコピーします.
4274 ワード
浅い層放射をもたらす暗黙放射生成子と放射対入演算子。
ソースコード
->暗黙的レプリケーションジェネレータのため、pAが指す位置はBが指す位置のメモリと同じです.
削除がdelete pAの場合、同じメモリを指すBの参照値は空になります.
私たちはトラブルに遭った.
これを浅い放射線と言います.
これらの問題を解決するには、開発者がレプリケーションジェネレータを明確に作成する必要があります.
6.4.6オブジェクト値によって呼び出される
: CObject a(b), CObject a = b; レプリケーション作成者を呼び出す
このようにして2回発生した場合を確認する.
しかし、もう一つあります.
すぐに!オブジェクトの値呼び出し.
void func(CObject a)
{
}
->レプリケーション作成者ではなく、レプリケーション作成者を呼び出します.
したがって、関数が終了すると、領域値になるため、消滅者も呼び出されます.
コストがかかるため、オブジェクトをパラメータとして送信するときに参照を使用することをお勧めします.
いいえ、パラメータとしてパラメータを使用する必要があります.
: CObject a(b), CObject a = b; レプリケーション作成者を呼び出す
このようにして2回発生した場合を確認する.
しかし、もう一つあります.
すぐに!オブジェクトの値呼び出し.
void func(CObject a)
{
}
->レプリケーション作成者ではなく、レプリケーション作成者を呼び出します.
したがって、関数が終了すると、領域値になるため、消滅者も呼び出されます.
コストがかかるため、オブジェクトをパラメータとして送信するときに参照を使用することをお勧めします.
いいえ、パラメータとしてパラメータを使用する必要があります.
パラメータの値としてオブジェクトを使用する場合.
ReferenStarに直接言わせて
->不要なオブジェクトの生成を禁止します.
=>パラメータとして入力した値が変更されないようにconstを追加する必要があります!
分かった点。
->ファジイが発生します.
レプリケーションジェネレータはいつ呼び出されますか?
初期化時にカッコで別のオブジェクトを囲み、
6.2.7コピーの防止方法
レプリケーションジェネレータと代入演算子を
->リンクエラーが発生します.
->コンパイルエラーが発生します.
//リンクエラーよりもコンパイルエラーの方が良いです.
:継承後、コピーする場合は、親もコピーする必要があります.親のコピー作成を制御することで、
止められる
この絵のようです.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はメモリ構造が異なりますが、値が同じなので、出力が同じと判断できます.
クラスで違います。
:複数の代入演算子を定義できるためです.
=>したがって、そのタイプに応じてオーバーロード関数を作成する必要があります.
Reference
この問題について(6.4.5. ジェネレータをコピーし、入力演算子をコピーします.), 我々は、より多くの情報をここで見つけました https://velog.io/@kwt0124/6.4.5.-복사-생성자와-복사-대입연산자テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol