2017-02-20 4 views
0

私は、いくつかのkey:value要素を持ついくつかのセグメントからなるconfigファイルを処理するクラスを開発しています。私がメインコードでcfgElementを宣言する場合、期待どおりもちろん、それはデストラクタをトリガし、C++クラスデストラクタをトリガする方法

class cfgElement { 
    public: 
     char  *key; 
     char  *val; 
     cfgElement *link; 

     cfgElement() { 
      key = nullptr; 
      val = nullptr; 
      link = nullptr; 
     } 

     ~cfgElement() { 
      if (key != nullptr) delete key; 
      if (val != nullptr) delete val; 
      key = nullptr; 
      val = nullptr; 
      link = nullptr; 
     } 
}; 

struct cfgSegment { 
    char  Name[16]; 
    cfgElement head; 
}; 

class config { 
    private: 
     cfgSegment *segments; 

    public: 
     config() { 
      segments = new cfgSegment[5]; 
     } 

     ~config() { 
      for (int i=0; i<5; i++) { 
       // Clean up segments[i].head 
      } 
     } 
}; 

:私は(ちょうど基本的な問題にまで切り詰め)次のコードを持っています。 segments[]配列の一部であるオブジェクトは、configオブジェクトが有効範囲外になったときにトリガされません。理由はわかりませんが、cfgElementデストラクタをトリガする方法がありますか?彼らはポインタではないので、私はdeleteできません。

私はcfgSegmenthead要素のポインタを作り、そしてconfigコンストラクタでsegments[]配列をループ、個別に各cfgElementを割り当てるが、それはそれを行うための唯一の方法であるだろうか?

+1

'delete [] segments;' work? forループなしの '〜config()'の中にあります。 –

+3

char *の代わりにstd :: stringを使い、スマートポインタ(つまりstd :: unique_ptr)を "生の"ポインタに置き換えて学ぶと、開発の容易さが増します。 – roalz

+2

@roalzはい、私は文字列とスマートポインタが使いやすくなっていることを理解していますが、私が学んでいるように、私はこれらの問題を理解するために難しいことをやりたいと思います。 – alanlittle

答えて

1

ループ内の各オブジェクトを削除する代わりに、セグメントを削除するだけで済みます。

~config() { 
     delete[] segments; 
    } 
+0

ええと、これまでにやったことがあると思っていましたが、コンパイラは配列の 'delete'について苦情を申しました。しかし、あなたのソリューションは広告として機能します。ありがとう! – alanlittle

+0

'delete'は単一のオブジェクトで動作し、' delete [] 'は配列で動作します。実際には両方のバリアントが動作するはずですが、配列上の 'delete'はメモリリークを引き起こします。 –

+0

実際、私が以前に試したことは、 'main()'の中では 'int x [5]でした。 delete [] x; 'そしてコンパイラは' [Warning]は配列 'x'を削除しています。私は違いが何であるか分からず、デストラクタに入れます。私が見る限り、それは本質的に同じものです。ああ、気にしない、違いが分かる。 'segments []'は実際には動的に割り当てられます。 – alanlittle

関連する問題