struct Foo
{
Foo(int i)
{
ptr = new int(i);
}
~Foo()
{
delete ptr;
}
int* ptr;
};
int main()
{
{
Foo a(8);
Foo b(7);
a = b;
}
//Do other stuff
}
私が正しく理解していれば、コンパイラは自動的にの代入演算子メンバー関数を作成しますFoo
。ただし、それはptr
inの値を取り、b
それをに入れa
ます。によって割り当てられたメモリはa
元々失われているようです。割り当てを行う前に電話をかけることはできましたがa.~Foo();
、デストラクタを明示的に呼び出す必要はめったにないという話をどこかで聞きました。したがって、代わりに、r値をl値に割り当てる前に、左のオペランドFoo
のポインターを削除する代入演算子を作成するとします。int
そのようです:
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
this->ptr = other.ptr;
}
return *this;
}
しかし、そうすると、スコープ外になるFoo a
とFoo b
、両方のデストラクタが実行されて、同じポインタが2回削除されません(両方が同じものを指しているため)。
編集:
Anders Kを正しく理解している場合、これが適切な方法です。
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
//Clones the int
this->ptr = new int(*other.ptr);
}
return *this;
}
ここで、が指しているをa
複製し、それへの独自のポインターを設定します。おそらくこの状況では、とはsだけを含むため必要ではありませんでしたが、データメンバーがそうではなく、そうでない場合は、再割り当てが必要になる可能性があります。int
b
delete
new
int
int*
Bar*
編集2: 最良の解決策は、コピーアンドスワップのイディオムのようです。