問題は、とデストラクタが呼び出され
たa
ときに同じ配列を 2 回削除していて、そのメンバー変数が同じメモリ位置を指していることです。を実行すると、 のコピーが作成され、 に割り当てられます。特定のコピー コンストラクターを定義していないため、コンパイラによって暗黙的に定義されています。ただし、値をコピーするだけです(期待どおりに割り当ては行いません)。t1
t2
t1
t2
a
Test t2 = f(t1)
t1
t2
a
new
ベスト プラクティスとして、独自のものを追加することをお勧めします:
- コンストラクターの
コピー - 代入のコピー
(cf rule of three
)
変数メンバーのa
設計に関して:
- 同じ配列を指したい場合t1
はt2
、使用できますshared_ptr
-独自の配列を持ちたい場合は、 for を使用する方がt1
簡単ですt2
vector<int>
a
編集:生のポインターを使用する必要がある場合に備えて、コピー コンストラクターと演算子の割り当てでメモリを管理する方法の簡単な例を次に示します。それについての参考書を読むことをお勧めできますか (たとえばEffective C++ , chapter 11
)。重要な概念と落とし穴について説明します。
class Test{
public:
int number;
int *a;
Test(int n){
a = new int[n];
}
~Test(){
delete [] a;
}
Test(const Test& that)
{
int size = sizeof(that.a);
a = new int[size];
memcpy (a, that.a, sizeof(size));
}
Test& operator=(const Test& that)
{
if (this != &that)
{
delete [] a;
int size = sizeof(that.a);
a = new int[size];
memcpy (a, that.a, sizeof(size));
}
return *this;
}
};
Test f(Test Ft1){
//do something
return Ft1;
}
int main(){
Test t1(3);
t1.number = 5;
Test t2 = f(t1);
// Test t3(t1); // calls copy constructor
// t3 = t1; // calls assignment operator
return 0;
}