删除非指针的通用列表

时间:2011-04-11 17:31:25

标签: c++ pointers generic-list delete-operator

我有一个带模板的通用列表

template<class t>
class GenericList {
    //the data is storeed in a chained list, this is not really important.
    struct c_list { t data; c_list* next; ...constructor... };

public:
    bool isDelete;
    GenericList() : isDelete(false) {...}

    void add(t d) {
        c_list* tmp = new c_list(d, first->next);
        //this is not really important again...
    }

    ~GenericList() {
        c_list* tmp = first;
        c_list* tmp2;
        while(tmp->next!=NULL) {
            if (isDelete) { delete tmp->data; } //important part
            tmp2=tmp->next;
            delete tmp;
            tmp=tmp2;

        }
    }
};

重要的部分是isDelete
 这只是示例代码

我需要这个,因为我想存储这样的数据:

GenericList<int> list;
list.add(22);list.add(33);

以及

GenericList<string*> list;
list.add(new string("asd")); list.add(new string("watta"));

问题如果我只存储<int>编译器说我不能删除非指针变量,但我不想在这种情况下。我怎么解决这个问题呢? 当我存储<int*>时,没有编译器错误......

3 个答案:

答案 0 :(得分:3)

在不改变代码的情况下,我会将您的问题解决为

template<class t>
class GenericList 
{
  //same as before

  //add this function template
   template<typename T>
   void delete_if_pointer(T & item) {}  //do nothing: item is not pointer

   template<typename T>
   void delete_if_pointer(T* item) { delete item; } //delete: item is pointer

  ~GenericList() {
       c_list* tmp = first;
       c_list* tmp2;
       while(tmp->next!=NULL) {
          delete_if_pointer(tmp->data); // call the function template
          tmp2=tmp->next;
          delete tmp;
          tmp=tmp2;
       }
   }
};

编辑:我刚注意到@ildjarn提供了类似的解决方案。但是有一个有趣的区别:我的解决方案在调用函数模板时不要求你提到data的类型;编译器自动推导出它。但是,@ ildjarn的解决方案要求您明确提及类型;编译器无法推断出他的解决方案中的类型。

答案 1 :(得分:1)

我会在你的类中创建一个嵌套的struct模板来帮助:

template<typename U>
struct deleter
{
    static void invoke(U const&) { }
};

template<typename U>
struct deleter<U*>
{
    static void invoke(U* const ptr) { delete ptr; }
};

然后从

更改使用isDelete的行
if (isDelete) { delete tmp->data; }

if (isDelete) { deleter<t>::invoke(tmp->data); }

答案 2 :(得分:0)

delete上的{p> int会导致程序格式错误,因此编译器会拒绝它,即使永远不会达到delete

只有从“裸”指针切换到智能指针(例如unique_ptrshared_ptr),才能实现所需;那些没有明确delete的处理内存管理。