【问题标题】:c++ destructors - when to use them and what is to be deletedc++ 析构函数 - 何时使用它们以及要删除的内容
【发布时间】:2012-05-20 03:47:16
【问题描述】:

我在当前的项目中遇到了困难。在以前的版本中,我使用了 std::vectors,一切都很好,没有内存泄漏,没有错误,很好。

然后我改用了一些指针,因为它更优雅,而且我的性能有所提高。

所以我有类似的课程

class A
{
    private:
        std::string str;
    public:
        A() {str = "";}
};

class B
{
    private:
        std::string str;
        A* a;
    public:
        B() {str = ""; a = NULL; }
};

class C
{
    private:
        std::vector<B*> bs;
    public:
        C() { bs = std::vector<B*>(); }

};

我知道每次使用new,之后我都必须delete。所以我为class Bclass C 创建析构函数。

我认为它应该是这样的:

B::~B()
{
    if ( this->a != NULL )
        delete this->a;
}

C::~C()
{
    while ( (this->bs).size() > 0 )
    {
        if ( (this->bs).back() != NULL )
            delete (this->bs).back();
        (this->bs).pop_back();
    }
    (this->bs).clear(); // not necessary since bs has size 0?
}

但是,我遇到了各种错误,例如 valgrind 中的“无效读取大小为 4”。

我认为析构函数应该是什么样子的想法可以吗? 我的代码还有什么问题? 将私有std::string 成员更改为std::string-pointers 会更好吗? 在析构函数中做str = "";是必要的还是好事?

附带说明:请理解我已经对“适当的析构函数”和类似关键字进行了大量搜索,但没有帮助。如果你认为这个问题被问得太频繁了:我不知道,因为我不明白。

【问题讨论】:

  • 啊哈哈哈哈——我觉得你对优雅的看法有点缺陷!至于效率……您是否进行了性能测试来证明这种提高??
  • “我使用了 std::vectors,一切都很好”。是的,std::vector 通常就是这种情况。这告诉你什么?
  • 我非常怀疑你仅仅使用new/delete而不是使用stl容器和智能指针就能获得300%的性能提升。
  • @stefan - 您提供了一个非常不完整的程序草图。如果您想获得比猜测更好的答案,请提供一个简短完整程序来演示问题。见sscce.org
  • 缺少main#includes,以及任何提及new 运算符的内容。缺少向您的vector 添加任何元素。即使添加了main,这个程序也不会产生你抱怨的错误。

标签: c++ class destructor


【解决方案1】:

Rob 所说的,你的析构函数也可以简化为:

B::~B()
{
    delete a;
}

C::~C()
{
    for (size_t i = 0; i < bs.size(); ++i)
        delete bs[i];
}

【讨论】:

  • 为什么不需要检查!= NULL?我认为删除 NULL 指针是非法的。
  • 引用 C++2003 标准第 5.3.5/2 节,“如果 delete 的操作数的值为空指针,则该操作无效。”
  • 只是一点点:正式(我坚持正式),C 的析构函数具有未定义的行为。 (实际上,它适用于所有实现,这是我不担心的罕见未定义行为之一。)
  • @James 你是指我的还是 OP 的?它有什么不明确的地方?
  • @AndreasBrinck 你的(和 OP 的)。该标准规定std::vector 中的所有值都必须是可复制的,指向已删除内存的指针不可复制。当然,1) 没有实现实际上会复制指针,除非你尝试用它做某事(或增加vector 的大小),以及 2) 复制指向已删除对象的指针不起作用的实现是至少在今天不存在。 (限制可以追溯到 C 的早期,在英特尔 80286 上的某些实现在复制已删除的指针时可能会出错。)
猜你喜欢
  • 2021-04-04
  • 1970-01-01
  • 2012-07-18
  • 2013-10-04
  • 2020-06-07
  • 2013-06-14
  • 2014-12-27
  • 2017-04-06
  • 1970-01-01
相关资源
最近更新 更多