我是来自boost的shared_ptr的新手,我正在考虑迭代我的设置以获得最佳对象。 编辑:添加了有关first_world
的信息std::set<World::CPtr> first_world = ... // long call, but it gets a set of constant shared pointers to the class World, where various methods exist
typedef boost::shared_ptr<World const> CPtr;
World::CPtr best = *(first_world.begin());
for (World::CPtr lo : first_world) {
if (best->getValue() >= lo->getValue() ){
best = lo;
}
}
后来我想使用那个共享指针,我的程序崩溃与Assertion`px!= 0'的通信失败。我遵循here的规则,我的意思是我在循环中使用了共享指针作为迭代器,但后来我将它分配给另一个指针。这是不好的做法,还有更好的做法吗?
cout << "name is: " << best->getDefinition() << endl;
答案 0 :(得分:0)
在那里粘贴的东西没有什么明显的错误,所以在创建该集合的长期通话中可能会出现错误。
例如,如果在向集合中添加元素时涉及原始指针,则很容易搞砸了。考虑这种情况,一个具体的例子,说明您的最佳实践链接中提到的一个常见错误:
std::set<World::CPtr> first_world;
World* pWorld = new World();
// Bad:
first_world.insert(World::CPtr(pWorld));
first_world.insert(World::CPtr(pWorld));
// Oops!! You now have two independently refcounted entries in first_world!
// emplace is just as deadly, but more subtle.
// Now you'll have three shared pointers in your set:
first_world.emplace(pWorld);
如果您查看first_world
中的条目并查看重复项,那么您就会知道自己遇到了麻烦。为了避免这样的错误,请确保只从其他shared_ptrs(或boost::make_shared
)构造shared_ptrs。
这样的提示#1:避免从原始指针构建shared_ptrs
。 (这包括this
指针,如果世界将自己添加到您的集合中...如果您正在这样做,最好开始使用Google搜索enable_shared_from_this
)。
现在让我们遵循该指南以获得预期的行为:
std::set<World::CPtr> first_world;
World::CPtr spWorld1 = boost::make_shared<World>();
World::CPtr spWorld2{spWorld1};
first_world.insert(spWorld1);
first_world.insert(spWorld2);
// Just one element in first_world now, as expected.
最后,一些(有点无关)的建议:
std::set
因为您已经声明它在比较条目时只查看堆上的World对象的地址。因此,如果堆上有两个逻辑上相同的不同世界,那么它们在集合中都有不同的条目。这是你的意图吗?如果你想避免逻辑重复,你需要插入你自己的自定义比较函数(std :: set的第二个模板参数)来对世界进行深度比较。first_world
在找到最大值之前不是空的,否则会发生不好的事情。std::max_element
算法而不是原始循环。 (这使得其他人更容易通过快速浏览来推断您正在做的事情。)