删除非指针的通用列表

发布于 2024-10-31 14:52:43 字数 1149 浏览 1 评论 0原文

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

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"));

如果我只存储 编译器说我不能删除非指针变量,但在这种情况下我不想这样做。我该如何解决这个问题?
当我存储 时,没有编译器错误...

I have a generic list with a template

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;

        }
    }
};

The important part is the isDelete
This is only a sample code

I need this because I want to store data like this:

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

and also

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

The problem if I store only <int> the compiler said that I cannot delete non pointer variables, but I don't want to in this case. How can I solve this?
when I store <int*> there is no compiler error...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深居我梦 2024-11-07 14:52:43

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

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 的解决方案要求您明确提及类型;编译器无法推断其解决方案中的类型。

Without changing much your code, I would solve your problem as

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;
       }
   }
};

EDIT: I just noticed that @ildjarn has provided similar solution. However there is one interesting difference: my solution does NOT require you to mention the type of data when calling the function template; the compiler automatically deduces it. @ildjarn's solution, however, requires you to mention the type explicitly; the compiler cannot deduce the type in his solution.

秋千易 2024-11-07 14:52:43

我会在类中创建一个嵌套结构模板来提供帮助:

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); }

I would create a nested struct template inside your class to help:

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

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

Then change the line that was using isDelete from

if (isDelete) { delete tmp->data; }

to

if (isDelete) { deleter<t>::invoke(tmp->data); }
哑剧 2024-11-07 14:52:43

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

只有从“裸”指针切换到智能指针(例如 unique_ptrshared_ptr),您想要的才可能实现;这些为您处理内存管理,无需显式删除。

delete on an int makes a program ill-formed, so the compiler will reject it, even though the delete would never be reached.

What you want is only possible if you switch from "bare" pointers to smart pointers such as unique_ptr or shared_ptr; those handle memory management for you, without explicit delete.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文