构造函数和析构函数中的std :: vector :: clear()

dim*_*mba 19 c++ stl

我在代码中多次遇到std :: vector类型为std :: vector的类成员的std :: vector :: clear()在构造函数和析构函数中调用.

我不明白为什么需要它:

  1. 构造函数 - 默认情况下,类型为std :: vector的类成员为空,因此无需调用clear().
  2. 析构函数 - 类型为std :: vector的类成员将被销毁,作为对象的标准销毁的一部分.作为载体销毁所有的部分价值的物品在它containied会被破坏(如果它堆中分配的内存指针,它们应该被"手动"已删除),因此又不需要调用清除().

我错过了什么吗?

Joh*_*ica 24

不,你没有遗漏任何东西.我怀疑这是(无害的)voodoo编程,有点像在释放它之后将指针设置为null,或者在GUI代码中随机调用repaint/revalidate.程序员记得它曾经帮助过某种类型的错误,现在不必要地添加它"以防万一".谁知道,也许它会有所帮助.巫毒.

  • 如果有的话,你想知道你删除了两次相同的指针.最好是大声失败(并发现它)而不是意外地成功(掩盖一个会回来咬你的bug) (12认同)
  • 将指针设置为null不是voodoo,它在调试中有很大帮助.还可以防止你两次删除相同的指针,但没有人这样做 - 对吧? (8认同)
  • @Mark:在dtor中将指针成员设置为NULL,它什么时候会完全消失?因为那是我们谈论的背景. (2认同)

Jer*_*fin 20

从事物的声音来看,编写该代码的人是那些错过了某些东西的人.在ctor或dtor中调用clear()的唯一时间是在其他代码的中间.例如,ctor可能读入一些数据,处理它,然后读入更多数据.在这种情况下,在读取数据时使用单个容器可能会更快,并且每次都清除它,而不是每次迭代创建一个新容器.


Mac*_*iek 7

  1. 这是COMPLETELY unnessecary以清除在构造一个STL容器的内容
  2. 清除析构函数中stl容器的内容是不可靠的,除非容器包含指针.如果指针是使用new创建的,则仍需要先删除它.在此之后,仍然不会对.clear容器感到厌烦.

考虑一下:

#define BOOST_TEST_MODULE StlContainers
#define BOOST_LIB_DIAGNOSTIC

#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/assign/std/vector.hpp>

#include <vector>

using namespace boost::assign;
using namespace std;

const vector<int> my_ints_vector = list_of(0)(1)(1)(2)(3)(5)(8)(13)(21)(34);

struct ScopedStruct1
{
        ScopedStruct1(const vector<int> & v) : m_v(v) {}
        ~ScopedStruct1() {}
    private :
        vector<int> m_v;
};

class A 
{ 
    public :
        A(int i) : m_i(i) {}
        ~A() {}
    private :
        int m_i;
};

struct ScopedStruct2
{
    ScopedStruct2() {}
    ~ScopedStruct2() { for(vector<A*>::iterator it = m_v.begin(); it != m_v.end(); ++it) delete *it; }

    vector<A*> m_v;
};

struct ScopedStruct3
{
    ScopedStruct3() {}
    ~ScopedStruct3() { /* no deletion */ }

    vector<A*> m_v;
};

BOOST_AUTO_TEST_CASE(StlContainer_storing_something_simple)
{
    ScopedStruct1 str(my_ints_vector);
}

BOOST_AUTO_TEST_CASE(StlContainer_storing_pointers_with_delete)
{
    ScopedStruct2 str;
    for(int i = 0; i < 10; i++)
        str.m_v.push_back(new A(i));
}

BOOST_AUTO_TEST_CASE(StlContainer_storing_pointers_without_delete)
{
    ScopedStruct3 str;
    for(int i = 0; i < 10; i++)
        str.m_v.push_back(new A(i));
}
Run Code Online (Sandbox Code Playgroud)

使用boost的unit_test框架我创建了3个测试用例.unit_test框架是greate,因为它跟踪内存泄漏.你会注意到第一和第二个测试用例不会产生内存泄漏,但第三种情况是因为不删除向量的内容.


Căt*_*tiș 5

不,你说得对.除非有需要,构造函数(或基类的构造函数)一些额外的业务,但机会是非常低的...

稍后编辑

在析构函数的情况下,我看到的一个最常见的错误是有些人认为clear方法也会调用指针向量的删除(向量),当然,情况并非如此