我有一个Foo对象,和一个std ::列表保持它的实例。我的问题是,当我添加一个新的实例列表中,它首先调用构造函数的但随后也析构函数。然后在另一实例中的析构函数(按照此指针)。

一个单个实例被添加到列表中,但因为它的析构函数被调用(与父母一起),不能被使用的对象的要求。

下面有一些简化的代码来说明这个问题:

#include <iostream>
#include <list>

class Foo
{
public:
    Foo()
    { 
        int breakpoint = 0;
    }
    ~Foo()
    { 
        int breakpoint = 0;
    }
};

int main()
{
    std::list<Foo> li;
    li.push_back(Foo());
}
有帮助吗?

解决方案

当你的push_back()你的Foo对象,该对象是的复制以列表的内部数据结构,因此,析构函数和另一实例的构造函数被调用。

在C所有标准STL的容器类型由++值取他们的物品,因此将它们复制根据需要。例如,每当一个矢量需要成长,有可能的是,在载体中的所有值被复制。

也许你想存储的指针而不是列表中的对象。通过这样做,只有指针被复制,而不是对象。但是,通过这样做,你必须确保删除对象一旦你完成:

for (std::list<Foo*>::iterator it = list.begin(); it != list.end(); ++it) {
    delete *it;
}
list.clear();

另外,也可以尝试使用某种“智能指针”类的,例如从Boost库。

其他提示

您在这里创建一个临时富:

li.push_back( Foo() )

的push_back将复制的Foo到其内部数据结构。的push_back已经执行后,临时的Foo被破坏,这将调用析构函数。

您将需要增加的类成员,你不想提前破坏某些引用计数正确的拷贝构造函数 - 或使其私人强迫自己上的指针解

使用此对象了解:

class Foo
{
public:
    Foo(int x): m_x(x)
    { 
    std::cout << "Constructed Object: " << m_x << ")\n";
    }
    Foo(Foo const& c): m_x(c.m_x+100)
    {
    std::cout << "Copied Object: " << m_x << ")\n";
    }
    ~Foo()
    {  
    std::cout << "Destroyed Object: " << m_x << ")\n";
    }
};

第一主

std::list<Foo*> li;
li.push_back(Foo(1));

下面我们创建临时Foo对象和呼叫的push_back()。临时对象被复制到列表和函数返回。在此声明,则临时对象被销毁(通过析构函数)完成。当列表被破坏它也将破坏其包含的所有obejcts(foo是与析构函数的对象,从而破坏包括调用析构函数)。

所以,你应该看到的财产以后这样的:

Constructed Object: 1
Constructed Object: 101
DestroyedObject: 1
DestroyedObject: 101

在第二个例子中您有:

std::list<Foo*> li;
li.push_back(new Foo(1));

下面动态创建在堆上的一个对象。然后调用的push_back()。在这里,指针被复制到列表(指针没有构造函数/析构函数),所以没有什么事情发生。列表现在包含一个指向堆上的对象。当函数返回别的什么都不做。当名单被破坏它破坏(注意微妙的差异中间人破坏和删除)(指针)它包含的对象,但指针没有析构函数所以什么也没有发生任何您将导致内存泄漏。

所以,你应该看到的财产以后这样的:

Constructed Object: 1

实际发生的这里是您将传递的对象的复制在列表中,因为你的价值,而不是通过引用发送。所以被称为实际上是叫你传递给方法的push_back对象上的第一个析构函数,但一个新的实例已经被创建,然后,它现在存储在列表中。

如果您不想储存指针的的对象的副本被创建,以的列表,而不是对象本身的对象。当然,这样做时,你将不得不在列表的破坏正常释放内存。

使得列表保持指针而不是实例解决了被称为与析构函数的问题。但我还是想了解为什么会发生。

#include <iostream>
#include <list>

class Foo
{
public:
    Foo()
    { 
        int breakpoint = 0;
    }
    ~Foo()
    { 
        int breakpoint = 0;
    }
};

int main()
{
    std::list<Foo*> li;
    li.push_back(new Foo());
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top