为什么添加到c++ STL向量中的对象的地址与其原始地址不同?

Why is the address of an object added to a C++ STL vector different than its original address?

本文关键字:地址 原始 添加 对象 STL c++ 向量 为什么      更新时间:2023-10-16

我有一个非常简单的方法来添加一个节点到一个图:

  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}

这到底是怎么回事?更重要的是,我该如何向一个向量中添加一个元素以便以后能找到它?

对象被复制到vector中,因此vector中存储的复制对象的地址肯定与原始对象的地址不同,因为没有两个不同的对象可以有相同的地址。

为了稍后找到你的对象,你可以将它与其他属性(它的一个或多个成员变量)进行比较,或者将它的索引存储在向量的某个地方。通常的方法是,每个对象都有一些"标识符"成员变量,至少对于存储在一个vector中的所有对象来说,该成员变量是唯一的。

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

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

如果不想将对象(类型为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(或boost智能指针[2])根据你的需要。

Boost也有指针容器[1].

另外,看看在Boost中如何实现图形。图[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

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