防止模板内存泄漏

Prevent memory leaks in template

本文关键字:内存 泄漏      更新时间:2023-10-16

我有模板

template <class T>
class A
{
  T* t_;
  A(){t_ = new T();}
  void SetItem(T& t)
  {
     t_ = t;
  }
};

此模板类有2种情况

1. A<T> a;
2. A<T*> b;

如果我调用两次SetItem,即

a.SetItem(T());
a.SetItem(T());

内存将被正确清理?

如果我这样调用也是一样的:

b.SetItem(new T());
b.SetItem(new T());

我知道记忆不会被清除。

问题:

  1. 如何在模板上约束它只需要TT*
  2. 如果我使用模板A<T*>如何防止泄漏。我应该修改课堂还是在外面处理它
  3. 当我使用A<T>A<T*>时,有什么方法可以让它工作吗

我认为使用智能指针或自动指针是一种选择。但我不确定。

快速的答案是,由使用类A的人来清理堆分配的内存。如果您使用std::list,并在其中存储指针,那么您(而不是列表)负责对它们调用delete。不要试图让模板化容器检测指针并删除它们。

我想,如果您使用带有指针模板param的类A,那么在某个时候,您会对GetItem()的返回调用delete(我认为该类会提供)。

(此外,SetItem应该取常量T&。)

为了避免泄漏,您应该有析构函数,当对象A被销毁时,它将deleteT。

要使您的模板只接受指针,您应该使用类型特征。我对它还不够熟悉,不能给你举个例子。

 template <class T>
    class A
    {
      T* t_;
     //Set t_ to nullptr, as you are able to pass new T() to SetItem
      A() : t_(nullptr) {}
      ~A() { delete t_; }  // When A is destroyed, t_ will be deleted.
      void SetItem(const T& t)
      {
         t_ = t;
      }
    };

A在这里是一个没有意义的类。不让它泄漏的解决方案是:

  • 使用智能指针。如果您的对象将被共享,而您不知道其生存期,则可以使用shared_ptr。如果不是,并且您的A类拥有该对象,请使用unique_ptr。

  • 根本不要使用指针,而是在a中使用t的实例。这会限制类a可能持有的类型,但类的用户可以通过将其作为参数化类型来使其持有unique_ptr或shared_ptr。一个例子是vector,它采用T类型的对象,但用户可以让他们的vector采用shared_ptr或unique_ptr。

  • 如果用户传入指针,则必须指定类是否拥有所有权。如果是这样的话,你的类本身就是一个智能指针。

在您的示例中很难确定使用哪一个,因为A在其现有形式中没有任何用途。