5

テンプレート化されたクラス myFoo があります。これは、プリミティブ型または複雑な型へのポインターのいずれかである T 型の「もの」を格納します。myFoo が削除されたら、たまたま格納されているすべてのものに関連付けられているすべてのメモリを解放したいと考えています。これは、格納されているすべてのポインターで削除を呼び出す必要があることを意味しますが、プリミティブで削除を呼び出すことになる可能性もあります。これは安全ですか??

何が起こっているのかをよりよく強調するために、以下に myFoo のスケッチを含めました。デストラクタの動作が適切に定義されているかどうかはわかりません。

template<class T>
class myFoo
{
   public:
       myFoo(int size) 
       { 
          size_ = size;
          T* foo = new T[size_]; 
       }

       void addFoo(T tmp, int index) 
       {
             foo[index] = tmp;
       }

       virtual ~myFoo()
       {
           for(int i=0; i < size_; i++)
           {
               delete foo[i];
           }
           delete [] foo;
       }

  private:
      int size_;
      T* foo;
}
4

2 に答える 2

5

呼び出すことができるdeleteのはポインター型だけです。たとえば、を呼び出すのはエラーdeleteです。intコードがエラーを実行しようとするようにテンプレートを調整すると、コンパイラはそれを通知し、コードのコンパイルを拒否します。

いいえ、「誤って」非ポインターを削除することを心配する必要はありません。

于 2012-07-25T05:43:00.850 に答える
1

テンプレートの専門化

template <class T> struct delete_it;

template <class T> struct delete_it<T*>
{
   static void func(T* ptr) { delete ptr; }
};

template <> struct delete_it<int>
{
   static void func(int) {}
};

template <> struct delete_it<double>
{
   static void func(double) {}
};

すべてのプリミティブ型について繰り返します。それで

   virtual ~myFoo()
   {
       for(int i=0; i < size_; i++)
       {
           delete_it<T>::func(foo[i]);
       }
       delete [] foo;
   }

未チェックのコード。

于 2012-07-25T06:16:47.687 に答える