我意识到在调用保存共享指针的vector.clear()
之后,由shared_ptr
拥有的对象的析构函数不会被释放。
代码示例如下所示。即使vector.clear()
被调用,在共享指针之后调用的析构函数超出了范围。我的问题是 - 我是否必须通过重置它们来手动删除向量内的所有智能指针?有没有更简单的方法可以提供建议?
Output :
constructor
I am here
destructor
Code:
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
A(){cout << "constructor" << endl;};
~A(){cout << "destructor" << endl;};
};
int main( )
{
shared_ptr<A> sharedptr (new A);
std::vector<shared_ptr<A> > test;
test.push_back(sharedptr);
test.clear();
cout << "I am here" << endl;
}
答案 0 :(得分:36)
在这种情况下,您有shared_ptr<A>
的两个副本,一个是sharedptr
变量,另一个是向量中的元素。
改为执行此操作
test.push_back(std::move(sharedptr));
现在请注意原始sharedptr
内部已移动且不再可用。另一件事是根本不做任何事情,这是对shared_ptr的完全有效的使用,sharedptr
将在超出范围后自行清理。
答案 1 :(得分:5)
当push_back
将shared_ptr
的副本添加到向量时,问题就出现了,原始悬空直到主要存在。如果不在主范围内创建shared_ptr,则不会发生此问题。只是避免在主范围内创建shared_ptr。将其作为push_back
电话中的临时权利。
Output is now:
constructor
I am almost there
destructor
I am here
New code:
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
A(){cout << "constructor" << endl;};
~A(){cout << "destructor" << endl;};
};
int main( )
{
vector<shared_ptr<A> > test;
test.push_back(shared_ptr<A>(new A));
cout << "I am almost there" << endl;
test.clear();
cout << "I am here" << endl;
return 0;
}
答案 2 :(得分:3)
这里 shared_ptr 和 vector 中的元素共享同一个对象,这将导致只调用一次构造函数和析构函数。
答案 3 :(得分:0)
直到以后才调用析构函数的原因是,变量sharedptr
仍在作用域中,直到main()
的结尾。如果您确实希望在此之前对其进行清理,则有几种解决方法。解决此问题的最明显方法是仅在快速块范围内使用sharedptr
:
int main( )
{
std::vector<shared_ptr<A> > test;
{
shared_ptr<A> sharedptr (new A);
test.push_back(sharedptr);
}
test.clear();
cout << "I am here" << endl;
}
或者,完全不要创建sharedptr
变量:
int main( )
{
std::vector<shared_ptr<A> > test;
test.push_back( shared_ptr<A>(new A) );
test.clear();
cout << "I am here" << endl;
}