繁体   English   中英

删除矢量类成员

[英]Delete vector class member

我有一个带有成员的A类,它是另一个B类的对象指针的向量

class A
{
    std::vector<B*> m_member_A

通过使用new运算符创建B的对象来填充m_member_A

B* b1 = new B;
m_member_A.push_back(b1);

在A的析构函数中,以下是否正确释放所有内容?

A::~A()
{
    for(int i = 0; i < m_member_A.size(); ++i)
    {
        delete m_member_A[i];
    }

    m_member_A.clear();
}

这是正确的,只要你还有一个正确的复制构造函数和复制赋值运算符,每三个规则 请注意, clear()是多余的,因为向量的析构函数将释放其内存。

你为什么乱搞指针和new 为什么不遵循Zero规则,如果需要指向多态的指针,请使用vector<B>vector<unique_ptr<B>> 那么你根本不需要担心析构函数,复制构造函数或复制赋值运算符; 你将获得移动语义作为奖励。

是的,这是正确的......但还不够。

每当复制A时,您还需要对容器进行深层复制。

如果你可以在向量中使用智能指针,那就更好了。 在你的头脑和你的代码中明确谁拥有什么。

几乎

如果在A的构造函数中构造(分配)B的元素,并且某些B抛出异常,则会发生内存泄漏(除非它在A的构造函数中被捕获,其中B的删除已完成)

而通常的三条规则。

可能有一些插图(请将MAKE_FAILURE调整为0或1):

#include <iostream>
#include <stdexcept>
#include <vector>

#define MAKE_FAILURE 0

static unsigned count;
const unsigned ExceptionThreshold = 3;
struct B {
    B() { if(ExceptionThreshold <= count++) throw std::runtime_error("Sorry"); }
    ~B() { std::cout << "Destruct\n"; }
};

struct A
{
    std::vector<B*> v;
    A()
    {
        for(unsigned i = 0; i < ExceptionThreshold + MAKE_FAILURE; ++i)
            v.push_back(new B);
    }

    ~A()
    {
        for(unsigned i = 0; i < v.size(); ++i) {
            delete v[i];
        }
    }
};

int main()
{
    A a;
    return 0;
}

你也可以进入浅层和深层复制的地形(如Orb的@Lightness Races所述)

这是在m_member_A向量中释放动态分配对象的内存的正确方法。 你实际上不需要打电话:

m_member_A.clear();

std :: vector将自己释放内存。

如果您可以使用C ++ 11,那么我建议更改为shared_ptr:

  std::vector<std::shared_ptr<B>> m_member_A

现在你不需要自己释放记忆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM