【发布时间】:2017-12-27 16:54:57
【问题描述】:
我有一个 std::vector 的对象通过在 push_back 调用中取消引用 std::unique_ptr 来填充。但是,当我运行基于可变范围的 for 循环时,我对这些对象的修改保留在循环的本地。换句话说,尽管循环中缺少const 关键字,但这些对象似乎被视为常量。这是演示我所看到内容的最少代码:
#include <vector>
#include <memory>
#include <iostream>
class Item
{
public:
typedef std::unique_ptr<Item> unique_ptr;
inline static Item::unique_ptr createItem()
{
return std::unique_ptr<Item>(new Item());
}
inline const int getValue() const { return _value; }
inline void setValue(const int val) { _value = val; }
private:
int _value;
};
int main()
{
std::vector<Item> _my_vec;
for (int i = 0; i < 5; i++)
{
Item::unique_ptr item = Item::createItem();
_my_vec.push_back(*item);
}
for (auto item : _my_vec)
{
// modify item (default value was 0)
item.setValue(10);
// Correctly prints 10
std::cout << item.getValue() << std::endl;
}
for (auto item : _my_vec)
{
// Incorrectly prints 0's (default value)
std::cout << item.getValue() << std::endl;
}
}
我怀疑这与std::unique_ptr 的移动语义有关?但这不太有意义,因为即使 push_back 正在调用复制构造函数或其他东西并复制添加的项而不是指向它,迭代器仍然会传递相同的副本,不是吗?
有趣的是,在我的实际代码中,这里由Item 表示的类有一个成员变量,它是指向另一个类的对象的共享指针vector,以及对这些共享指针指向的对象的修改在循环之间持续存在。这就是为什么我怀疑unique_ptr 有什么奇怪的地方。
谁能解释这种行为并解释我如何在仍然使用指针的同时解决这个问题?
【问题讨论】:
-
使用
for (auto& item : _my_vec)。没有&,它按值访问 -
@pergy:哦,伙计.... duh。你说得对。我花了很多时间迭代我的共享指针容器,我忘记了如何正确地迭代实际对象。谢谢你。只是去展示它通常是如何显而易见的。马,不是斑马,等等……
-
很好地提出了问题:)
-
@marcman 如果您尝试修改的内容被视为常量,它将无法编译。
-
@LogicStuff:这就是我如此困惑的原因。当然比那简单多了……
标签: c++ c++11 pointers smart-pointers unique-ptr