【发布时间】:2010-07-10 01:27:25
【问题描述】:
我想我并不完全理解析构函数在 C++ 中是如何工作的。这是我为重现问题而编写的示例程序:
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
struct Odp
{
int id;
Odp(int id)
{
this->id = id;
}
~Odp()
{
cout << "Destructing Odp " << id << endl;
}
};
typedef vector<shared_ptr<Odp>> OdpVec;
bool findOdpWithID(int id, shared_ptr<Odp> shpoutOdp, OdpVec& vec)
{
shpoutOdp.reset();
for (OdpVec::iterator iter = vec.begin(); iter < vec.end(); iter++)
{
Odp& odp = *(iter->get());
if (odp.id == id)
{
shpoutOdp.reset(iter->get());
return true;
}
}
return false;
}
int main()
{
OdpVec vec;
vec.push_back(shared_ptr<Odp>(new Odp(0)));
vec.push_back(shared_ptr<Odp>(new Odp(1)));
vec.push_back(shared_ptr<Odp>(new Odp(2)));
shared_ptr<Odp> shOdp;
bool found = findOdpWithID(0, shOdp, vec);
found = findOdpWithID(1, shOdp, vec);
}
就在main()结束之前,这个程序的输出是:
Destructing Odp 0
Destructing Odp 1
为什么会这样?我保留了对向量中每个 Odp 实例的引用。它与通过引用传递shared_ptr 有关吗?
更新我认为shared_ptr::reset 减少了引用计数,基于MSDN:
运算符都减 资源的引用计数 当前由 *this 拥有
但也许我误解了它?
更新 2:看起来这个版本的 findOdpWithID() 不会导致调用析构函数:
bool findOdpWithID(int id, shared_ptr<Odp> shpoutOdp, OdpVec& vec)
{
for (OdpVec::iterator iter = vec.begin(); iter < vec.end(); iter++)
{
Odp& odp = *(iter->get());
if (odp.id == id)
{
shpoutOdp = *iter;
return true;
}
}
return false;
}
【问题讨论】:
-
您在下面的评论中提到您正在尝试减少引用计数。你不应该担心这一点。共享指针的工作是担心引用计数等实现细节。你应该使用它。您可以将 shared_ptr 想象成 java 指针,它在幕后完成您需要的所有工作。
-
这不是一个好问题。你提到了一个“问题”,但没有告诉我们它是什么,并抱怨你的程序的输出,但没有告诉我们你的期望。我们无法预测您在脑海中所期望的行为,尤其是实际行为——本质上是正确的 C++ 行为——是我们所期望的!
标签: c++ destructor