【问题标题】:Can I call delete on primitives?我可以在原语上调用 delete 吗?
【发布时间】:2012-07-23 12:15:22
【问题描述】:

我有一个模板类 myFoo,它存储 T 类型的“东西”,可以是原始类型,也可以是指向复杂类型的指针。当 myFoo 被删除时,我想释放与它碰巧存储的所有内容相关的所有内存。这意味着我需要在存储的每个指针上调用 delete,但我也可能最终在原语上调用 delete。这样安全吗?

我在下面添加了 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;
}

【问题讨论】:

  • 你不能专攻指针吗?
  • 正如所写,您的代码对于 any 类型 T 没有意义,至少在语义上:您混淆了所有权责任,并且该类将是可用性、可读性和可维护性的噩梦。简而言之,不应该关心T 是什么,客户应该自己进行清理(或者当然使用智能指针)。
  • @KerrekSB:我正在编写各种数据库。我想在其中插入数据。数据库拥有我存储在其中的内容的内存所有权是有意义的。否则我需要在外部管理数据库中的所有数据。有点“wtf??”如果我按照你的建议去做。
  • 什么是“wtf??”关于使用智能指针?我认为您存储复杂类型指针的原因是因为它们太重而无法复制?让客户决定他的类型是否太重。如果是的话,他可以让T成为智能指针,那么你就不用担心删除了。
  • 此外,这条线T* foo = new T[size_]; 没有做你想做的事。它在构造函数中创建一个 local 指针,并在你离开构造函数时立即泄漏内存。

标签: c++ templates destructor delete-operator


【解决方案1】:

您唯一可以调用delete 的是指针类型。例如,在 int 上调用 delete 是错误的。如果你安排你的模板,让你的代码尝试做一些错误的事情,编译器会让你知道并拒绝编译你的代码。

所以不,您不必担心“意外”删除非指针。

【讨论】:

  • 那么我怎样才能实现我描述的行为呢?
  • 您可以使用不同的模板,具体取决于您是否要存储指针。或者,您可以存储智能指针类的实例,并依靠智能指针的析构函数进行删除。
  • 谢谢格雷格。我认为您(和其他人)已经让我相信智能指针是必经之路。
【解决方案2】:

模板专业化

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

未经检查的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2016-12-15
    • 2021-02-19
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    相关资源
    最近更新 更多