これは間違いではありませんが、それは良い考えではありません。あなたが返された後
MyClass& doSomething() {
return *(new MyClass());
}
、誰もが元のポインタを持っていないので、誰もがそれ史上delete
ます。*だから、メモリリークです。
対応するdelete
またはそれ以上のスマートポインタコンストラクタがない限り、new
を書くことはほとんどありません。
一方、元のコードでこの行:
MyClass a = doSomething();
...とにかく値のコピーを作成しようとしています。それが修正されなければならない別のバグではないと仮定すると、なぜヒープ割り当てをオブジェクトに割り当て、コピーとリークの参照を返しますか?オブジェクトを値で返すだけです。
MyClass doSomething() {
return MyClass();
}
ヒープ上に何も作成していないので、何も削除することを心配する必要はありません。
ベストプラクティスは、通常、RAII:Resource Acquisition Is Initializationの4文字で集計できます。 (そしてその結果、その破壊は解放されます。)あなたが値段で回ることは不可能な、あるいは高価な何かを持っているなら、価値によってそれにいくらかのハンドルを渡します。例:
unique_ptr<MyClass> doSomething() {
return unique_ptr<MyClass>(new myClass());
}
unique_ptr<MyClass> a = doSomething();
これは単なるポインタのコピーです。オブジェクトはdoSomething
内に作成され、a
がスコープ外になると削除されます(または、別の変数に渡した場合は、がスコープ外になるなど)。
一方、MyClass
が簡単にコピーできる値のほんの一握り**である場合は、コピーしてください。
*それが今までそれを削除する不可能ではありません。あなたはいつもリファレンスへのポインタをとることができ、それはdelete
です。あなたがそうすることはほとんどありません。それは厄介なように見えます。ポインタを渡す場合は、ポインタを渡します。ポインタを渡す必要がない場合は、クラス内で所有権をラップし、値でクラスを渡します。
**簡単にコピーできるとは、を安全ににコピーして、実際にそうすることを意味します。例えば、生のポインタやファイルハンドルは数バイトで、デフォルトのコピーコンストラクタはあなたを喜んでコピーしますが、同じヒープオブジェクトやファイルへの複数の参照が終わることになります。誰がそれを削除または閉鎖するかを担当しています。
constは必要ありません。最初のオプションは良いです。また、必要に応じてポインタを返すこともできます。あなた次第。 –
しかし、参照は呼び出し元によって割り当てられませんでした。呼び出し中にインスタンス化されました。新しいものを使用しなかった場合、ヒープではなくスタック上にあるため、範囲外になります。 –
@BrianCain彼は絶対に 'new'を必要とします。そうしないと、' doSomething() 'が終了するとすぐにオブジェクトが破壊されるからです。 –