47

私の知る限り、作成したすべてのものをデストラクタで破棄し、new開いているファイル ストリームやその他のストリームを閉じる必要があります。ただし、C++ の他のオブジェクトについては疑問があります。

  • std::vectorおよびstd::strings: それらは自動的に破棄されますか?

  • 私が次のようなものを持っている場合

    std::vector<myClass*> 
    

    クラスへのポインタの。ベクトル デストラクタが呼び出されるとどうなりますか?
    のデストラクタを自動的に呼び出しますmyClassか? または、ベクターのみが破棄されますが、それに含まれるすべてのオブジェクトはメモリ内にまだ存在していますか?

  • クラス内に別のクラスへのポインターがある場合はどうなりますか。たとえば、次のようにします。

    class A {
      ClassB* B;
    }
    

    クラス A は、コードのある時点で破棄されます。クラス B も破棄されますか、それともポインタとクラス B だけがメモリのどこかにまだ存在しますか?

4

7 に答える 7

52

std::vector と std::strings: それらは自動的に破棄されますか?

はい (メンバー変数がstd::vectorおよびへのポインターではないと仮定しますstd::string)。

std::vector のようなものがある場合、ベクトル デストラクタが呼び出されるとどうなりますか? myClass のデストラクタを自動的に呼び出すでしょうか? または、ベクターのみが破棄されますが、それに含まれるすべてのオブジェクトはメモリ内にまだ存在していますか?

その場合vector<MyClass>、ベクトルに含まれるすべてのオブジェクトが破棄されます。その場合vector<MyClass*>、すべてのオブジェクトを明示的にdeleted にする必要があります (破棄されるクラスが 内のオブジェクトを所有していると仮定しますvector)。3 番目の選択肢はvector、 のようなスマート ポインターですvector<shared_ptr<MyClass>>。この場合、 の要素を明示的にdvectorにする必要はありません。delete

クラス内に別のクラスへのポインタがあるとどうなりますか

Bを明示的に指定する必要がありますdelete。ここでも、スマート ポインターを使用して の破棄を処理できますB

于 2012-08-22T08:18:54.787 に答える
6

動的に作成したメモリについてのみ心配する必要があります ( でメモリを予約する場合new)。

例えば:

Class Myclass{
   private:
       char* ptr;
   public:
       ~Myclass() {delete[] ptr;};
}
于 2012-08-22T08:26:04.027 に答える
3
  • それらが自動ストレージにある場合は、はい。を持つことができますがstd::string* s = new std::string、その場合は自分で削除する必要があります。

  • 所有しているメモリを手動で削除する必要があります(で割り当てられたメモリの場合new)。

  • で割り当てbた場合newは、デストラクタで明示的に破棄する必要があります。

経験則として、コード内でdelete/delete[]for eachを使用するnew/new[]ことをお勧めします。

より良い経験則は、RAII を使用し、生のポインターの代わりにスマート ポインターを使用することです。

于 2012-08-22T08:19:25.990 に答える
3

場合によります。std::vectorそしてstd::stringMyClassすべてに共通点が1つあります。変数をこれらの型のいずれかとして宣言すると、スタックに割り当てられ、現在のブロックに対してローカルになり、そのブロックが終了すると破棄されます。

例えば

{
    std::vector<std::string> a;
    std::string b;
    MyClass c;
} //at this point, first c will be destroyed, then b, then all strings in a, then a.

ポインターに到達した場合は、正しく推測できます。ポインター自体が占有するメモリ (通常は 4 バイト整数) のみが、スコープを離れるときに自動的に解放されます。delete明示的に指定しない限り(ベクトル内にあるかどうかに関係なく)、指しているメモリには何も起こりません。他のオブジェクトへのポインターを含むクラスがある場合は、デストラクタでそれらを削除する必要がある場合があります (そのクラスがそれらのオブジェクトを所有しているかどうかによって異なります)。C++11 には、「通常の」オブジェクトと同様の方法でポインターを処理できるポインター クラス (スマート ポインターと呼ばれる) があることに注意してください。

元:

{
    std::unique_ptr<std::string> a = make_unique<std::string>("Hello World");
    function_that_wants_string_ptr(a.get());
} //here a will call delete on it's internal string ptr and then be destroyed
于 2012-08-22T08:25:50.857 に答える
2

std :: vectorのようなものがある場合、ベクトルデストラクタが呼び出されるとどうなりますか?

場合によります。

のベクトルがある場合、ベクトルstd::vector <MyClass>のデストラクタは、ベクトルMyClass内ののすべてのインスタンスに対してデストラクタを呼び出します。

ポインタ のベクトルがある場合はstd::vector <MyClass*>、のインスタンスを削除する必要がありますMyClass

クラス内に別のクラスへのポインタがある場合はどうなりますか

ClassBインスタンスはメモリに残ります。ClassAデストラクタを使用してジョブを作成する方法として考えられるのはB、インスタンスメンバーまたはスマートポインタを作成することです。

于 2012-08-22T08:20:55.877 に答える
1
  1. はい。std::vectorstd::stringはスコープ外になると自動的に、含まれているオブジェクトのデストラクタも呼び出します ( for std::vector)。

  2. 前述のように、std::vectorスコープ外になると破棄され、含まれるオブジェクトのデストラクタが呼び出されます。しかし実際には、この場合、含まれているオブジェクトはポインターであり、ポインターが指すオブジェクトではありません。したがって、deleteそれらを手動で行う必要があります。

  3. (2)と同じ。A は破棄されるため、ポインターは破棄されますが、クラス B はポイントされません。deleteA とBのデストラクタを提供する必要があります。

C++11 には非常に便利な解決策があります: use std::unique_pointer. 単一のオブジェクトを指すためにのみ使用できます。これは、ポインターが範囲外になると削除されます (たとえば、 を破棄する場合std::vector)。

http://en.cppreference.com/w/cpp/memory/unique_ptr

于 2012-08-22T08:37:28.797 に答える
1

std::vectorstd::stringおよび私が知る限り、他のすべての STL コンテナには自動デストラクタがあります。これが、代わりにこれらのコンテナを使用する方がよい理由でありnewdeleteメモリ リークを防ぐことができます。

デストラクタは、ベクターがオブジェクトへのポインターのベクター( ) ではなく、オブジェクトのベクター ( )myClassである場合にのみ呼び出されます。myClassstd::vector< myClass >myClassstd::vector< myClass* >

最初のケースでは、 のデストラクタは、その要素ごとにstd::vectorのデストラクタも呼び出します。myClass2 番目のケースでは、 のデストラクタが のデストラクタstd::vectorを呼び出しますmyClass*。つまり、各ポインタを格納するために使用されたスペースは解放されますが、myClassオブジェクト自体を格納するために使用されたスペースは解放されません。

指しているClass Bオブジェクトは破棄されませんが、そのポインターを格納するために割り当てられたスペースは解放されます。

于 2012-08-22T08:34:16.440 に答える