スコープポインタの目的は何ですか? 私の理解では、スコープ ポインターはコード ブロック内のメモリを管理します。ブロック内で変数を宣言したい場合は、スタック上で宣言するだけで、クリーニングについて心配する必要はありません。
4 に答える
スタックベースのデータとは異なり、scoped_ptrにはreset()メンバーがあります。つまり、心ゆくまで構築/破棄できます。operator unspecified-bool-type
これにより、任意の時点で構築されたオブジェクトがあるかどうかを示すフラグとしてnullポインタを(技術的に)使用できます。また、必要に応じて、可変スコープとは独立して構築/破棄を順序付けることができます。
また、scoped_ptrは、スタック変数としてだけでなく、クラスメンバーとして宣言できることを考慮してください。ドキュメントでは、scoped_ptrを使用してhandle / bodyイディオムを実装することを提案しています(クラスの実装の詳細を非表示にするため)。
最後に、DeadMGのポイント「動的タイプでない場合」について詳しく説明するために、scoped_ptrを使用してポリモーフィック操作を実装できます。
{
scoped_ptr<Base> a( mode ? new DerivedA : new DerivedB );
a->polymorphic_function();
}
単純なスタックベースの割り当てでは、これを行うことは実際には不可能です。
動的なサイズまたはタイプの場合はそうではありません。さらに、スコープ付きポインターはスワップでき、C++11 ではunique_ptr
移動できるため、厳密にはスコープされません。
ポイントは、特定のレキシカルスコープ内でポインターを作成およびクリーンアップできることです。これはさまざまな状況で役立ちます。また、 if を明示的delete
に使用することを忘れることにより、メモリ リークが発生しないことが保証されますが、これは推奨されません。new
boost::scoped_ptr
はコピー不可であり、その存続期間全体にわたってそのリソースを完全に所有することに注意してください。これによりboost::shared_ptr
、リソースをコピーしたり、誤って共有したりすることが回避されるため、より安全になります。
{ //Some Scope
boost::scoped_ptr<int> i_ptr;
// do something with pointer
} // leave scope, pointer is cleaned up
通常、スレッドスタックにはメモリ制限があります(スレッドスタックサイズを参照)。
また、ポインタが外部から渡され、このスコープで削除する必要がある場合もあります(たとえば、例外がスローされた場合、その行より下のdelete呼び出しは実行されません)。したがって、ポインタを自動的に魔法のようにクリーンアップする必要があります
void foo(Object*obj)
{
//this will ensure that object gets cleaned up even if doFoo() throws an exception
boost::scoped_ptr<Object> objCleaner(obj);
obj->doFoo();
}