防止模板中的内存泄漏

时间:2012-02-07 09:48:09

标签: c++ templates memory-leaks

我有模板

template <class T>
class A
{
  T* t_;
  A(){t_ = new T();}

  void SetItem(T& t)
  {
     t_ = t;
  }

};

此模板类有两种情况

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*>时,有没有办法让这项工作成功?
  4. 我认为使用智能指针或自动指针是一种选择。但我不确定。

3 个答案:

答案 0 :(得分:4)

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

我想如果你使用带有指针模板参数的A类,那么在某些时候你会在GetItem()返回时调用delete(我假设该类会提供)。

(另外,SetItem应该采用const T&amp;。)

答案 1 :(得分:0)

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

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

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

    };

答案 2 :(得分:0)

A在这里是一个毫无意义的课程。不泄漏的解决方案是:

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

  • 根本不要使用指针,而是在A中使用T的实例。这会对A类可能包含的类型设置限制,但是类的用户可以使其保持unique_ptr或shared_ptr将其作为参数化类型。一个例子是vector,它接受类型为T的对象,但是用户可以使它们的向量采用shared_ptr或unique_ptr。

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

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