矢量内存管理 我使用Borland 2006 C++,并有以下代码。我正在使用向量,并且很难理解为什么没有调用析构函数

矢量内存管理 我使用Borland 2006 C++,并有以下代码。我正在使用向量,并且很难理解为什么没有调用析构函数,c++,C++,基本上我有a级 class A { private: TObjectList* list; int myid; public: __fastcall A(int); __fastcall ~A(); }; __fastcall A::A(int num) { myid = num; list = new TObjectList(); } __fastcall A::~A() { delete list; } int main(int argc,

基本上我有a级

class A
{
private:
    TObjectList* list;
    int myid;
public:
 __fastcall A(int);
 __fastcall ~A();
};

__fastcall A::A(int num)
{
    myid = num;
    list = new TObjectList();

}

__fastcall A::~A()
{
    delete list;
}

int main(int argc, char* argv[])
{
    myfunc();
    return 0;
}

void myfunc()
{
    vector<A*> vec;
    vec.push_back(new A(1));
    vec.push_back(new A(2));
}
A类
{
私人:
TObjectList*列表;
int-myid;
公众:
__快速呼叫A(int);
__快速调用~A();
};
__快速调用A::A(int num)
{
myid=num;
list=新的TObjectList();
}
__快速呼叫A::~A()
{
删除名单;
}
int main(int argc,char*argv[])
{
myfunc();
返回0;
}
void myfunc()
{
向量向量机;
向量推回(新A(1));
向量推回(新A(2));
}
根据我读到的内容,当变量vec超出myfunc()的作用域时,它应该析构函数包含的元素,因此应该调用A的析构函数。我在~a()处有一个断点,但从未被调用,我也尝试过resize()和erase方法


TIA

vec在超出范围时会破坏其元素。这里的问题是vec的元素是指向对象的指针,而不是对象本身。如果你真的这么做了

vector<A> vec;
vec.push_back(A(1));
vec.push_back(A(2));
vec;
向量推回(A(1));
向量推回(A(2));
…然后事情就会如你所期望的那样


ETA:不过请注意,如果您这样做,您必须为a定义一个复制构造函数。这应该包括对TObjectList成员进行深度复制。否则,当你复制一个对象时,你会发现两个对象都指向同一个TObjectList,当第二个对象被销毁时,你的程序会崩溃。

vec在超出范围时会销毁它的元素。这里的问题是vec的元素是指向对象的指针,而不是对象本身。如果你真的这么做了

vector<A> vec;
vec.push_back(A(1));
vec.push_back(A(2));
vec;
向量推回(A(1));
向量推回(A(2));
…然后事情就会如你所期望的那样


ETA:不过请注意,如果您这样做,您必须为a定义一个复制构造函数。这应该包括对TObjectList成员进行深度复制。否则,复制一个A对象时,两个对象都指向同一个TObjectList,当第二个对象被销毁时,程序将崩溃。

不会调用
A
的析构函数,因为没有
A
的向量。您有一个指向
a
的指针向量,并调用指针的析构函数。指针没有析构函数,因此不会发生任何事情

删除所有内容的一种方法是手动执行以下操作

while (!vec.empty())
{
    delete vec.back();
    vec.pop_back();
}

未调用
A
的析构函数,因为没有
A
的向量。您有一个指向
a
的指针向量,并调用指针的析构函数。指针没有析构函数,因此不会发生任何事情

删除所有内容的一种方法是手动执行以下操作

while (!vec.empty())
{
    delete vec.back();
    vec.pop_back();
}

抓取Boost库,在上面有原始指针的地方使用Boost::shared_ptr。(好的,不在main()的签名中。)

抓取Boost库,在上面有原始指针的地方使用Boost::shared\u ptr。(好吧,不是在main()的签名中。)

已经有很多好的答案了,但我将再添加一个:


使用来自的boost::ptr_向量,而不是std::vector。当向量超出范围时,它将删除对象,从而调用析构函数。

已经有很多好的答案,但我将再添加一个:


使用来自的boost::ptr_向量,而不是std::vector。当向量超出范围时,它将删除对象,从而调用析构函数。

作为旁注。在容器中使用指针时,不要尝试使用auto_ptr进行销毁。由于STL容器的复制方式不同,Auto_ptr无法在STL容器中使用。对,但是boost::shared_ptr又名std::tr1::shared_ptr在容器类中工作得很好。感谢您的解释,另一个快速的问题是,当我向vector添加一个元素时,析构函数会被调用两次,当vec超出范围时会再次调用,我希望它在复制和添加元素时调用一次。不,应该调用两次。发生的情况是,您正在创建一个临时的匿名对象,并将其传递给vector的push_-back方法。Vector然后将该临时对象的副本作为对象进行内部存储。从push_back返回后,临时A对象立即脱离范围并被销毁。然后,当向量本身超出范围并自毁时,它将自毁它所持有的复制对象。这就是为什么您需要一个副本构造函数来为一个进行正确的深度复制的对象创建副本。在容器中使用指针时,不要尝试使用auto_ptr进行销毁。由于STL容器的复制方式不同,Auto_ptr无法在STL容器中使用。对,但是boost::shared_ptr又名std::tr1::shared_ptr在容器类中工作得很好。感谢您的解释,另一个快速的问题是,当我向vector添加一个元素时,析构函数会被调用两次,当vec超出范围时会再次调用,我希望它在复制和添加元素时调用一次。不,应该调用两次。发生的情况是,您正在创建一个临时的匿名对象,并将其传递给vector的push_-back方法。Vector然后将该临时对象的副本作为对象进行内部存储。从push_back返回后,临时A对象立即脱离范围并被销毁。然后,当向量本身超出范围并自毁时,它将自毁它所持有的复制对象。这就是为什么您需要一个复制构造函数来为一个进行正确的深度复制的对象创建一个复制构造函数。