Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 防止模板内存泄漏_C++_Templates_Memory Leaks - Fatal编程技术网

C++ 防止模板内存泄漏

C++ 防止模板内存泄漏,c++,templates,memory-leaks,C++,Templates,Memory Leaks,我有模板 template <class T> class A { T* t_; A(){t_ = new T();} void SetItem(T& t) { t_ = t; } }; 内存将被正确清理 如果我这样调用,也是一样的: b.SetItem(new T()); b.SetItem(new T()); 我知道记忆不会被清除 问题: 如何对模板进行约束,使其仅需T或T* 如果我使用模板A如何防止泄漏。我应该修改课程还是在外面处理

我有模板

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

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

};
内存将被正确清理

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

b.SetItem(new T());
b.SetItem(new T());
我知道记忆不会被清除

问题:

  • 如何对模板进行约束,使其仅需
    T
    T*
  • 如果我使用模板
    A
    如何防止泄漏。我应该修改课程还是在外面处理
  • 每当我使用
    A
    A
    时,有什么方法可以使这项功能发挥作用吗

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

    为了避免泄漏,您应该有析构函数,当对象
    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;
          }
    
        };
    
    模板
    甲级
    {
    T*T_;
    //将t_u设置为nullptr,因为您可以将新的t()传递给SetItem
    A():t_(nullptr){}
    ~A(){delete t_;}//当A被销毁时,t_2将被删除。
    无效设置项(常数T&T)
    {
    t=t;
    }
    };
    
    为避免泄漏,应配备析构函数,当对象
    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;
          }
    
        };
    
    模板
    甲级
    {
    T*T_;
    //将t_u设置为nullptr,因为您可以将新的t()传递给SetItem
    A():t_(nullptr){}
    ~A(){delete t_;}//当A被销毁时,t_2将被删除。
    无效设置项(常数T&T)
    {
    t=t;
    }
    };
    
    快速的答案是,由使用类A的人来清除堆分配的内存。如果您使用std::list并在其中存储指针,那么您(而不是列表)负责对它们调用delete。不要试图让模板化容器检测指针并删除它们

    我可以想象,如果将类A与指针模板param一起使用,那么在某个时刻,您将在从GetItem()返回时调用delete(我假设该类将提供)


    (另外,SetItem应该采用常量T&)

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

    我可以想象,如果将类A与指针模板param一起使用,那么在某个时刻,您将在从GetItem()返回时调用delete(我假设该类将提供)


    (另外,SetItem应该采用常量T&)。

    a在这里是一个无意义的类。避免泄漏的解决方案有:

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

    • 完全不要使用指针,而是在a中使用t的实例。这会限制类a可能持有的类型,但类的用户可以通过将其作为参数化类型输入,使其持有唯一或共享的类型。一个例子是vector,它接受T类型的对象,但用户可以让他们的向量接受shared_ptr或unique_ptr

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


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

    A在这里是一个无意义的类。避免泄漏的解决方案有:

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

    • 完全不要使用指针,而是在a中使用t的实例。这会限制类a可能持有的类型,但类的用户可以通过将其作为参数化类型输入,使其持有唯一或共享的类型。一个例子是vector,它接受T类型的对象,但用户可以让他们的向量接受shared_ptr或unique_ptr

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


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

    您使用的是C++11还是C++03?这些代码都不能正常工作,请修复它。
    std::auto_ptr
    将是一个更好的选择,为您省去了大量关于谁负责删除内存的麻烦。我会试试std::auto_ptr,看看您是否喜欢它。只需确保类文档让用户知道类A拥有该对象并将销毁它。更好的办法是让他们把一个自动ptr交给ctor。当您将auto_ptr复制到您的会员auto_ptr时,auto_ptr将无效。@userbb-您应该接受其中一个答案,否则人们以后就不会麻烦了!:)您使用的是C++11还是C++03?这些代码都不能正常工作,请修复它。
    std::auto_ptr
    会是一个更好的选择,为您省去了大量关于谁负责删除内存的麻烦。我会尝试std::auto_ptr,看看您是否喜欢它。只需确保类文档让用户知道类A拥有该对象并将销毁它。更好的办法是让他们把一个自动ptr交给ctor。当您将auto_ptr复制到您的会员auto_ptr时,auto_ptr将无效。@userbb-您应该接受其中一个答案,否则人们以后就不会麻烦了!:)那么自动ptr不是一个好的解决方案?当我使用它时,会发生什么不好的事情呢?这取决于使用您的类来管理堆分配内存的人-使用auto_ptr是他们可以做到的一种方法。所以auto_ptr
     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;
          }
    
        };