私のクラスには、動的に割り当てられたメモリ領域への静的ポインタが必要です。私はそれを初期化する方法を理解しています-私の場合、最初のオブジェクトがそれを必要とするときに初期化します。しかし、それを解放するためのコードのいつ/どこでそれがわからない。プログラムの終了時に解放したいのですが。
オブジェクトのデストラクタでポインタを解放できるかもしれませんが、オブジェクトが最後に使用されているときに解放しても安全かどうかを確認するために、オブジェクト数を維持する必要があります。
これを行うよりエレガントな方法はありますか?
私にお知らせください。
ありがとう、jbu
ここには2つの解決策があります。
2を実行することをお勧めします。これは、非常にクリーンな方法です。
これは簡単な例です。これを行う代わりに
static Thing* things = new Thing(); // or whatever way to initialize, here or in a specific function
あなたはそれをします:
class ThingManager // or whatever name you like
{
public:
ThingManager( Thing* thing ) : m_thing( thing ) { }//or create it here? whatever solution suits your way of creating the data
~ThingManager() { delete m_thing; } // THAT's the important part!
Thing* instance() const { return m_thing; } // or whatever accessor you need, if you need one
private:
Thing* m_thing;
};
その後
static ManagedThing thing; // now i can access it via thing.instance()
プログラムが終了すると、静的変数(ポインターではなくなります)が破棄され、そのデストラクターが呼び出されます。
それはあなたにそれをどのように行うことができるかについての考えをあなたに与えるためだけに書かれています。
スマートポインターに入れます。静的な有効期間があり、main
が戻った後に破棄されます:
static std::auto_ptr<T> thePointer;
もう1つのオプションは、独自のatexit
関数を登録することです。
// static
void YourClass::freePointer(void)
{
delete getPointer();
}
// static
T* YourClass::getPointer(void)
{
if (!thePointer)
{
thePointer = new T;
atexit(freePointer);
}
return thePointer;
}
同じ効果があります。あなたがすでに述べた別のオプションは、静的なカウンターを維持することです。実際にはかなり効果的にまとめることができます。
OSの観点から見ると、プログラムが終了するときにメモリを解放することには意味がありません。遅い終了だけです。アプリケーションの終了により、アドレス空間全体が破壊され、解放されますすべてヒープに一度に割り当てます。アプリのシャットダウン時に明示的にfree
を呼び出すと、ヒープ内のポインターがシャッフルされ、とにかく捨てられます。
すべてを明示的に解放するために一生懸命努力する主な理由は、メモリリークが発生せず、メモリフットプリントが永久に増大しないことを確認するためです。
しかし、これが静的であり、1つしか存在せず、他のすべてのオブジェクトが解放されるまで安全に解放できないことが確実である場合、これは、アプリケーションを許可するだけの方が良い場合です。終了はあなたのためにそれを世話します。
静的変数をスマートポインターとして宣言すると、プログラムが終了すると、割り当てられたポインターが解放されます。
デストラクタが実行されるときにオブジェクトインスタンスカウントを追跡するためにクラスに静的カウンターを定義し、カウンターをデクリメントします。counter== 0の場合もメモリを解放します。