元の質問については、はい、そのようなポインターに再割り当てできます。ポインタはメモリ アドレスだけを保持し、それ以上のものは保持しません。
しかし、実際にはこれを行うべきではありません。このような生のポインターを処理するとバグが発生する可能性があるためです。コードには既にそれらのいくつかがあります。最新の C++ では、この方法をより適切に、心配することなく行うことができます。この (コンパイル可能な) コードから始めるとします。Obj を int に置き換えましたが、それがクラスではなくネイティブ型であるという事実は問題ではありません。
#include <iostream>
struct Foo
{
int* pObj;
Foo() : pObj(NULL) {}
};
int* CreateObj()
{
return new int(42); //obj is a class
}
int main()
{
Foo foo;
foo.pObj = CreateObj();
std::cout << *foo.pObj << std::endl;
delete foo.pObj;
foo.pObj = new int(13);
std::cout << *foo.pObj << std::endl;
delete foo.pObj;
}
これを次のように変換できます。
#include <iostream>
#include <memory>
struct Foo
{
std::unique_ptr<int> pObj;
Foo() : pObj(NULL) {}
};
std::unique_ptr<int> CreateObj()
{
return std::unique_ptr<int>(new int(42));
}
int main()
{
Foo foo;
foo.pObj = CreateObj();
std::cout << *foo.pObj << std::endl;
foo.pObj = std::unique_ptr<int>(new int(13));
std::cout << *foo.pObj << std::endl;
}
主な変更点は、生のポインターを削除してunique_ptr
ラッパーに置き換えたことです。これにはいくつかの利点があります。
- 所有権を明確に述べ
unique_ptr
ています。現在のスコープのみが所有できます。createObj はオブジェクトを作成しますが、一時的な (名前のない) オブジェクトを返すunique_ptr
ことで所有権を解放し、呼び出し元がいつでもオブジェクトを削除できるようにします。これにより、トリッキーなメモリリークが回避されます。
unique_ptr
がスコープ外になったとき、またはオーバーライドされたとき (たとえば、代入演算子によって) に、削除は自動的に行われます。