【发布时间】:2016-06-25 10:23:43
【问题描述】:
我正在阅读一些关于智能指针如何在 C++ 中工作的教程,但我坚持使用我尝试的第一个:唯一指针。我遵循wikipedia、cppreference 和cplusplus 的指导方针。我也看过this answer。如果我理解正确,唯一指针应该是唯一拥有某个内存单元/块所有权的指针。这意味着只有唯一指针(应该)指向该单元格,而没有其他指针。来自维基百科,他们使用以下代码作为示例:
std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; //Compile error.
std::unique_ptr<int> p3 = std::move(p1); //Transfers ownership. p3 now owns the memory and p1 is rendered invalid.
p3.reset(); //Deletes the memory.
p1.reset(); //Does nothing.
直到第二行,当我测试它时,这对我来说效果很好。但是,在将第一个唯一指针 移动 到第二个唯一指针之后,我发现两个指针都可以访问同一个对象。我认为整个想法是让第一个指针变得无用可以这么说?我期望一个空指针或一些未确定的结果。我运行的代码:
class Figure {
public:
Figure() {}
void three() {
cout << "three" << endl;
}
};
class SubFig : public Figure {
public:
void printA() {
cout << "printed a" << endl;
}
};
int main()
{
unique_ptr<SubFig> testing (new SubFig());
testing->three();
unique_ptr<SubFig> testing2 = move(testing);
cout << "ok" << endl;
int t;
cin >> t; // used to halt execution so I can verify everything works up til here
testing->three(); // why is this not throwing a runtime error?
}
这里,testing 已经移动到了testing2,所以我惊讶地发现我仍然可以在testing 上调用方法three()。
此外,调用 reset() 似乎并没有像它所说的那样删除内存。当我将main方法修改为:
int main()
{
unique_ptr<SubFig> testing (new SubFig());
testing->three();
unique_ptr<SubFig> testing2 = move(testing);
cout << "ok" << endl;
int t;
cin >> t;
testing.reset(); // normally this should have no effect since the pointer should be invalid, but I added it anyway
testing2.reset();
testing2->three();
}
这里我希望three() 不适用于testing2,因为来自维基百科的示例提到应该通过重置来删除内存。我仍在打印 printed a 好像一切都很好。这对我来说似乎很奇怪。
那么谁能给我解释一下原因:
- 从一个唯一指针移动到另一个唯一指针不会使第一个指针无效吗?
- 重置实际上并没有删除内存?调用
reset()时实际发生了什么?
【问题讨论】: