析构函数和智能指针给C2541

时间:2015-03-06 12:06:25

标签: c++

我试图在我的程序中使用一些shared_ptr向量,但这样做会给我一个C2541错误:"删除":无指针的对象无法删除。我发现它与我的类的析构函数有关(至少有一个...)所以我试着改变它们 - 没有成功:( 我的应用程序包含一个类A,它包含两个向量:一个是shared_ptrs到B类的对象,另一个是shared_ptrs到A类的对象。 以下是我的代码的一些部分:

//A.cpp
A::~A(void)
{
    for(std::vector<BPtr>::iterator it = allBs.begin(); it != allBs.end(); ++it) 
    {   //loop that deletes all Bs
        delete it->get();
    }

    for(std::vector<APtr>::iterator it = allAs.begin(); it != allAs.end(); ++it) 
    {    //loop that (should) delete all As (and their As and Bs)
        delete it->get();
        delete it.operator*;
    }
}

//A.h
class A
{
public:
typedef std::shared_ptr<A> APtr; 
typedef std::shared_ptr<B> BPtr; 
// some more stuff
private:
std::vector<BPtr> allBs;
std::vector<APtr> allAs;
}

我得到错误两次:一个来自该行     删除it.operator *; 另一个是在memory.h内部引起的。 我首先有一个额外的递归函数删除了树,并被析构函数调用,但经过一番思考后,我认为调用&#34;删除&#34;在析构函数中(行&#34;删除它 - &gt; get();&#34;)也会这样做。

3 个答案:

答案 0 :(得分:3)

你做错了。

std::shared_ptr等智能指针的全部目的是您不必手动删除它们指向的内容。实际上,您一定不能手动删除它。智能指针假定指向者的所有权 - 它将在适用时自行删除它。适用于std::shared_ptr,&#34;适用时&#34;表示&#34;指向对象的最后一个std::shared_ptr被销毁。&#34;

因此,只需完全删除析构函数,您就不需要它了。当向量被破坏时,它们将破坏所有包含的std::shared_ptr。这将减少指针的引用次数。如果有任何变为零,它们将自动delete d(由shared_ptr析构函数)。

答案 1 :(得分:1)

您可以而且必须delete仅使用new创建的内容。只有这一次,没有别的。删除可以手动完成&#34;#34;或者让std::shared_ptr这样的智能指针为你做(这是一个非常好的主意)。使用智能指针时,您可以(并且应该)摆脱new,转而使用std::make_sharedstd::make_unique

同样适用于new[]delete[]

这意味着在你的析构函数中没有delete的空间,因为你永远不会new编辑任何内容并让它由原始指针拥有(这很好)。

答案 2 :(得分:1)

您不希望delete shared_ptr一个reset的内容,这是它的工作。只需it->reset(); 智能指针:

{{1}}