【问题标题】:Clearing std::vector of pointers with std::unary_function用 std::unary_function 清除指针的 std::vector
【发布时间】:2017-11-13 05:05:36
【问题描述】:

在他的“Effective STL”中,Meyers 展示了如何正确清理指针向量(std::vector::clear 只删除他的指针,而不是它们占用的内存)。

所以他建议在调用clear 之前使用for_each 和调用对象析构函数的unary_function:

template<typename T> struct DeleteMyObject2: public std::unary_function<const T*, void>
{
    void operator()(const T* ptr);
};

template<> struct DeleteMyObject2<algotest::ImageSelection>
{
   void operator()(const algotest::ImageSelection* ptr)
   {
       delete ptr;
       ptr=0; // this was added by me 
   }
};

void std_clearing_pointers()
{
   std::vector<ImageSelection*> vec;
   vec.reserve(5);
   for(int i=0; i<5; ++i)
       vec.insert(vec.begin(), new ImageSelection());

   std::for_each(vec.begin(), vec.end(), DeleteMyObject2<ImageSelection>());

   // HERE elements of vec are not NULL !!! 
   vec.clear();
} 

在书中DeleteMyObject2 被调用时不带括号,它不能编译(问题1:为什么?标准被改变了?):

std::for_each(vec.begin(), vec.end(), DeleteMyObject2<ImageSelection>);

无论如何,如果为DeleteMyObject2 调用operator(),它会编译,但在vector 中的vec.clear() 对象之前不是NULL。我想随着 STL 容器一直在复制它们的元素,ImageSelection 指针是按值传递的,所以一切正常(question2:我说的对吗?)。

我尝试通过 ref 传递指针,现在对象在for_each 之后为 NULL,我觉得更安全。

template<> struct DeleteMyObject1<algotest::ImageSelection>
{
    void operator()(algotest::ImageSelection*& ptr)
    {
        delete ptr;
        ptr=0;
    }
 };

question3DeleteMyObject2 是否比DeleteMyObject1 更可取,因为它没有不必要的分配?

提前致谢。

【问题讨论】:

    标签: c++11 vector stl destructor unary-function


    【解决方案1】:

    自从 Effective STL 出现以来,就有了更短、更易读的方法来做到这一点。例如,你现在可以写

    vector<int *> a{new int{1}, new int{2}};
    for_each(begin(a), end(a), [](int *p){delete p;});
    

    其中[](int *p){delete p;}lambda or, anonymous, functiondelete 任何p 的表示,其代码比您问题中的任何一个类都短得多。

    顺便说一句,您可能还想考虑智能指针的vector(例如,vector&lt;shared_ptr&lt;int&gt;&gt; 表示指向整数的指针向量)。用于释放资源的显式代码容易出错。

    至于你的问题:

    1. 应该出现在括号中,用括号表示你想要这个类的(默认构造的)对象。该函数需要一个对象,而不是一个类。

    2. 可以按值传递指针(在这种情况下)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      • 2016-02-19
      • 2011-03-18
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多