为什么添加到C++ STL向量的对象的地址与原始地址不同?
我有一个非常简单的方法,增加了一个节点图:为什么添加到C++ STL向量的对象的地址与原始地址不同?
template<class T>
void AdjacencyList<T>::add(const GraphNode<T>& node) {
_nodes.push_back(node);
}
在另一种方法,我遍历_nodes
向量,按地址寻找添加的节点:
for (unsigned int i = 0; i < _nodes.size(); i++) {
if (&(_nodes[i]) == &node)
// do something
}
然而,这是不行的,因为当我添加node
到_nodes
载体,新增加的成员有不同的地址:
Graph::AdjacencyList<int>::add (this=0x8052338, node=...) at ../AdjacencyList.h:42
42 _nodes.push_back(node);
(gdb) p node
$1 = (const Graph::GraphNode<int> &) @0xbffff39c: {value = 123}
(gdb) n
43 }
(gdb) p _nodes[0]
$4 = (Graph::GraphNode<int> &) @0x80522b0: {value = 123}
世界正在发生什么?更重要的是,我应该如何将一个成员添加到矢量中,以便以后可以找到它?
因为它是一个不同的对象。所有标准容器都拥有它们的对象,并且您在标准容器中使用的所有类型都必须是可复制的。
当您将对象传递给push_back
时,它将被复制到矢量中。如果你希望稍后能找到它,你的对象类型必须有一个平等的概念,你可以比较和查找等价对象。 (或者,或者你必须记住你将每个对象放置在向量中的哪个位置。)
这样做很有道理,现在我想起来了,图中两个节点相同值,所以我应该为我的'GraphNode'类定义一个==运算符来比较值。谢谢你的帮助,我会尽快接受你的答案;) – 2011-04-19 07:16:22
我不认为这很愚蠢。你可能会有不同的graphd noe,它们在图形中保持相同的值,但链接不同。可能不会在你的情况下。然而, – ysdx 2011-04-19 07:33:03
@ysdx:是的,你说得很对,这也是我原来的意图。我认为需要为每个节点分配一个UUID来处理这个问题,但是,在这种特殊情况下,我很幸运不需要支持同一个值的多次出现 - 我或多或少地模拟了一个网络拓扑,设备A不能出现超过一次 - 至少,我希望**就是这样。 ;) – 2011-04-19 08:50:17
对象复制到矢量中,因此存储在矢量内的副本的地址肯定不同于原始对象的地址,因为没有两个不同的对象可以具有相同的地址。
以后要找到你的对象,你可以通过一些其他属性(它的一个或多个成员变量)来比较它,或者将它的索引存储在向量中。通常的做法是每个对象都有一些“标识符”成员变量,它至少对于存储在一个向量内的所有对象是唯一的。
正确答案,谢谢。我接受查尔斯的回答只是因为他提供了一些关于“我该如何做这件事?“我的问题的方面:) – 2011-04-19 07:18:00
@Josh Glover:当然,随时可以这样做 – sharptooth 2011-04-19 07:22:44
如果不想将对象(类型T)的副本推送到容器中,则可以使用容器T的智能指针:
std::vector< std::shared_ptr< Graph::GraphNode<int> > > c;
std::shared_ptr< Graph::GraphNode<int> > p = std::shared_ptr< Graph::GraphNode<int> >(new Graph::GraphNode<int>(whatever));
c.push_back(c);
有了这个,你可以比较指针。
根据您的需要,您可以使用auto_ptr,shared_ptr,unique_ptr(或增强智能指针[2])。
Boost也有指针容器[1]。
此外,看图如何在Boost.Graph [3]中实现。您可能想要使用类似的方法。
[1] http://www.boost.org/doc/libs/1_46_1/libs/ptr_container/doc/ptr_container.html
[2] http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/smart_ptr.htm
[3] http://www.boost.org/doc/libs/1_46_1/libs/graph/doc/table_of_contents.html
啊,是的,智能指针。这是一个绝妙的解决方案 - 远胜于我对UUID的想法。 – 2011-04-19 08:50:57
作为一个经验法则记住STL用途复制语义。因此,除非STL容器是指针集合,否则添加到STL集合的任何元素将复制复制。
感谢所有伟大的答案,伙计们! – 2011-04-19 08:52:24