2011-04-19 48 views
2

我有一个非常简单的方法,增加了一个节点图:为什么添加到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} 

世界正在发生什么?更重要的是,我应该如何将一个成员添加到矢量中,以便以后可以找到它?

+0

感谢所有伟大的答案,伙计们! – 2011-04-19 08:52:24

回答

2

因为它是一个不同的对象。所有标准容器都拥有它们的对象,并且您在标准容器中使用的所有类型都必须是可复制的。

当您将对象传递给push_back时,它将被复制到矢量中。如果你希望稍后能找到它,你的对象类型必须有一个平等的概念,你可以比较和查找等价对象。 (或者,或者你必须记住你将每个对象放置在向量中的哪个位置。)

+0

这样做很有道理,现在我想起来了,图中两个节点相同值,所以我应该为我的'GraphNode'类定义一个==运算符来比较值。谢谢你的帮助,我会尽快接受你的答案;) – 2011-04-19 07:16:22

+0

我不认为这很愚蠢。你可能会有不同的graphd noe,它们在图形中保持相同的值,但链接不同。可能不会在你的情况下。然而, – ysdx 2011-04-19 07:33:03

+0

@ysdx:是的,你说得很对,这也是我原来的意图。我认为需要为每个节点分配一个UUID来处理这个问题,但是,在这种特殊情况下,我很幸运不需要支持同一个值的多次出现 - 我或多或少地模拟了一个网络拓扑,设备A不能出现超过一次 - 至少,我希望**就是这样。 ;) – 2011-04-19 08:50:17

5

对象复制到矢量中,因此存储在矢量内的副本的地址肯定不同于原始对象的地址,因为没有两个不同的对象可以具有相同的地址。

以后要找到你的对象,你可以通过一些其他属性(它的一个或多个成员变量)来比较它,或者将它的索引存储在向量中。通常的做法是每个对象都有一些“标识符”成员变量,它至少对于存储在一个向量内的所有对象是唯一的。

+0

正确答案,谢谢。我接受查尔斯的回答只是因为他提供了一些关于“我该如何做这件事?“我的问题的方面:) – 2011-04-19 07:18:00

+0

@Josh Glover:当然,随时可以这样做 – sharptooth 2011-04-19 07:22:44

1

如果不想将对象(类型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

+0

啊,是的,智能指针。这是一个绝妙的解决方案 - 远胜于我对UUID的想法。 – 2011-04-19 08:50:57

1

作为一个经验法则记住STL用途复制语义。因此,除非STL容器是指针集合,否则添加到STL集合的任何元素将复制复制

相关问题