5
matrix m1(5,5); 
matrix m2(5,5); 
m1 = matrix(m2); 

上記のコード (任意のクラス、行列) では、m2 の情報がコピーされたときに、m1 に関連付けられた情報に対してデストラクタが呼び出されますか?

4

4 に答える 4

5

いいえ、割り当てオペレーターは、割り当てm1を実行する前に、リソースが保持している可能性があるものを解放する必要があります。m1デストラクタは、スコープ外に出ようとしている場合にのみ呼び出されます。

于 2012-04-14T02:37:16.640 に答える
3

いいえ、スタックに割り当てられたオブジェクトが構築されると、スコープ外になるか、デストラクタを明示的に呼び出すまで(おそらく絶対に行わないでください)、分解されません。したがって、この場合、matrixがオーバーロードされたoperator =(const matrix&rhs)メンバー関数を定義すると、operator =()が呼び出され、rhsがm1にコピーされます。それ以外の場合は、デフォルトの割り当てが使用され、一時的なmatrix(m2)オブジェクトからm1にすべてのメンバー変数がコピーされ、これらの変数の以前の値が上書きされます。

于 2012-04-14T02:40:58.667 に答える
1

行列がデストラクタを適切に実装しているかどうか、および代入演算子がどのように実装されているかによると思います。マトリックスに機能するデストラクタがあり、マトリックスが「割り当てスワップ」(コピースワップイディオムと同様)を使用している場合は、はいM1を適切に解放する必要があります。

これに加えて、m1 = m2を呼び出すときにMatrix(m2)は実際には必要ありません。これは、コピーコンストラクターを呼び出してから、一時的なコピーをm1に割り当てるだけです。したがって、無駄な作業が行われています。

于 2012-04-14T02:39:28.000 に答える
1

このマトリックスは何のコンテナですか? 値であれば問題ありません。スマートポインタなら問題ありません。

しかし、通常のポインターが含まれている場合はどうなるでしょうか。あとは の実装次第ですmatrix::operator=(const matrix&)。そこでデストラクタを呼び出す必要がある場合は、それらを呼び出す必要があります。それは魔法のように起こるわけではなく、これらのことについて考える必要があります。

一般に、通常のコンテナー クラスを使用して通常のポインターを保持することはお勧めできません。デストラクタが呼び出されない場合、メモリ リークが発生します。デストラクタが呼び出された場合、別のポインタを介して同じオブジェクトにアクセスするとクラッシュします。(同じオブジェクトへのポインターを含む 2 つのマトリックスがあるとします。)

通常のコンテナー クラスを使用して通常のポインターのコンテナーを処理することは困難であり、危険であるためです。この目的には、専用のコンテナーまたは専用のポインターを使用する必要があります。

たとえば、Boost には、ポインターを保持するための特別なコンテナー クラスが含まれています。Boost には、通常のコンテナーが保持できる共有ポインター クラスもあります。

何が起こるべきかを決めるだけです。もしそうなら、同じ基本オブジェクトへのポインターを保持するa=b;必要がaありますか? それとも、内部的に指すbために新しいオブジェクトを作成する必要がありますか?a

于 2012-04-14T02:51:44.027 に答える