2016-06-13 2 views
-1

は以下の不自然な例を考えてみましょう:クラスの複数のインスタンスを動的に割り当てられたオブジェクトのリストを共有する必要があるかどうかはさておき実装ファイルで静的マップに動的に割り当てられたオブジェクト。削除は必要ですか?

class AllocatedClass { 
public: 
    AllocatedClass() : dummy(0) {} 
private: 
    int dummy; 
}; 

class AllocatingClass { 
public: 
    AllocatingClass() : list() {} 
    ~AllocatingClass() { 
     // CANNOT delete the elements in list here because there may 
     // be more than on instance of AllocatingClass sharing the same 
     // static list 
    } 
    AddNewObject() { 
     list.push_back(new AllocatedClass()); 
    } 
private: 
    static std::vector<AllocatedClass*> list; 

}; 

std::vector<AllocatedClass*> AllocatingClass::list; 

は、良いアイデアですプログラムの終わりにこれらの新しいAllocatedClassオブジェクトをクリーンアップする方法がありますか?アプリケーションの終了時まで削除したくないと考えれば、削除されることは決してないでしょうか?

+4

[std :: shared_ptr](http://en.cppreference.com/w/cpp/memory/shared_ptr)の使用はどうですか? – WhiZTiM

+3

すべての 'new()'はそれに対応する 'delete'を見る必要があります。 –

+0

このコードは単純にコンパイルできません。 VTC。 – SergeyA

答えて

2

オブジェクトの有効期間がプログラムの実行期間である場合、コードでメモリを解放する必要はありません。メモリは自動的にフリーになります。

Linuxのコマンドラインツールの多くは、パフォーマンス上の理由からメモリ内のコードを解放しません。

もう1つの戦略は、一意のAllocatedClassインスタンスの別のリストを保持し、後でそのリストから解放することです(オブジェクトの所有権を切り替えることです)。 )。 std::list<AllocatedClass*> to_be_freedのように。

+9

デストラクタには副作用があり、削除は常にメモリを解放するだけではありません。 – GManNickG

+1

シャットダウンに時間がかかるプログラムは、非常に迷惑です。したがって、プログラムの終了時に割り当て解除のステップを安全に排除でき、プログラムの実行時間を短縮するのに有益な場合は、それを実行してください。あなたがしていることを知っていることを確認してください。 –

-1

動的割り当てオブジェクトを作成するオブジェクトのほとんどは、オブジェクトの寿命が終了したときにメモリを解放するプログラマ定義のデストラクタを持つ必要があります。 newで動的メモリを割り当てるため、AllocatingClassにはデストラクタが必要です。

~AllocatingClass() { 
    for (int i = 0 ; i < list.size();i++) { 
     if(list[i] != NULL) { 
      delete list[i]; 
      list[i] = NULL; 
     } 
} 

これは、すでに削除されたポインタを削除しないように、メモリと安全性の割り当てを解除する方法を提供します。

+0

これは必要ありません。 'list'は静的で共有されていますが、最初の'〜AllocatingClass'で削除しています。 AllocatingClassがシングルトンである場合、それは何らかの標準実装を使用する必要があります。 –

+0

@AndrewLazarusそれは動的に割り当てられたリストを共有する可能性を無視すると言われています。 – Stephen

+0

私が読んでいるところでは、それは受け入れ可能なスタイルかどうかでコード戦争に入るのではなく、その設定ではうまくいかないコードを書くのはOKではないと言います。 –

1

方法が終わり、プログラムの でこれらnew'ed AllocatedClassオブジェクトをクリーンアップがありますか?

解決策の1つは、std::shared_ptrを使用し、自動的に割り当てを解除することです。

#include <memory> 
#include <vector> 
#include <iostream> 

class AllocatedClass 
{ 
    public: 
     AllocatedClass(int n = 0) : dummy(n) {} 
     ~AllocatedClass() { std::cout << "I am being destroyed" << '\n'; } 
    private: 
     int dummy; 
}; 

class AllocatingClass 
{ 
    public: 
     AllocatingClass() {} 
     void AddNewObject(int num = 0) 
     { shared_list.push_back(std::make_shared<AllocatedClass>(num)); } 
    private: 
     static std::vector<std::shared_ptr<AllocatedClass>> shared_list; 
}; 

std::vector<std::shared_ptr<AllocatedClass>> AllocatingClass::shared_list; 

AllocatingClass ac; 

int main() 
{ 
    ac.AddNewObject(); 
    ac.AddNewObject(1); 
} 

Live Example

デストラクタは、ベクター中に配置されたオブジェクトのために自動的に呼び出されることに留意されたいです。

(ちなみに、メンバー変数にはlistという名前を付けてください。)

+0

「私は破壊されています。私はベクトルのコメントを描くことができます。「今、私は世界の駆逐艦Deathになっています。それは狂った笑いです。 – user4581301

+0

オブジェクトが実際に共有されていない場合、それらは 'vector'の中にのみ存在し、' std :: unique_ptr'は 'std :: shared_ptr'より意味があります。もちろん、 'vector 'から 'Vector 'に 'vector'を変更し、' shared_list.push_back(std :: make_shared (num))を変更することは、 ; '' shared_list.push_back(num); 'に置き換え、STLがあなたのためにメモリを扱わせるようにします。 –

関連する問題