使用std :: unary_function清除std ::指针向量

时间:2017-06-11 18:30:21

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

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

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

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

无论如何,如果为operator()调用DeleteMyObject2,但在向量中的vec.clear()对象之前不是NULL,则编译它。我想当STL容器一直复制它们的元素时,ImageSelection指针按值传递,所以一切都好( question2 :我是否正确?)。

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

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

问题3 DeleteMyObject2DeleteMyObject1更优先,因为它没有不必要的分配?

提前致谢。

1 个答案:

答案 0 :(得分:1)

自从有效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<shared_ptr<int>>作为整数指针的向量)。解除分配资源的显式代码很容易出错。

关于你的问题:

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

  2. 可以按值传递指针(在本例中)。