在C++语言中,标准集合实际上包含对象,而在其他语言中,如python或java,它们实际上包含了存储在别处的对象的<EM>引用EME>(或指针)。但是,由于C++不包含垃圾回收,所以必须明确管理对象的生命周期<EM>别处<EEM>。在</p>
<P>设计的结果是,为了允许在两个不同的集合中使用同一个对象,您<>强>必须/s>使用指针或引用集合(谨防,C++不直接允许引用集合;但是,为此创建了{{CD1>})。在</p>
<p>根据您的用例,您可以使用原始指针(如果已经管理了实际对象的生存期),也可以使用内部管理引用计数的智能指针(这里是<code>std::shared_ptr</code>),以确保在销毁最后一个<code>shared_ptr</code>时自动销毁该对象。这离Python对对象的引用不远,前提是您知道最后一个<code>shared_ptr</code>的销毁实际上会销毁对象(*)。换一种说法,如果你不想让它悬挂起来,就不要保留任何其他的指针或引用。在</p>
<p>或者,如果集合不是对称的,也就是说,如果一个集合实际包含所有对象,而另一个集合只包含对前一个集合的对象的引用-<em>引用</em>将是您的最佳选择,而第二个集合可能是<code>std::vector<std::reference_wrapper<Car>></code>。在</p>
<hr/>
<p>根据MvG注释添加。在</p>
Python对象和C++ SyrdY-PTR之间可能存在恼人的区别。Python有一个完整的垃圾收集器,它非常聪明,可以检测循环引用,并在没有外部引用时立即销毁循环。示例:</p>
<pre><code>>>> b = ['x']
>>> a = ['y']
>>> b.append(a)
>>> a.append(b)
>>> a
['y', ['x', [...]]]
>>> b
['x', ['y', [...]]]
</code></pre>
<p>a包含对b的引用,其中包含对a的引用。。。在</p>
<p>如果a被删除(或超出范围),b仍将包含整个链</p>
^{pr2}$
<p>但如果a和b都被删除(或超出范围),gc将检测到不再有外部ref,并将销毁所有内容。在</p>
遗憾的是,如果您使用^ {CD2>}来管理C++对象的循环,因为它只使用本地REF计数,每个对象都有一个REF到另一个,并且它们永远不会被删除,即使它们将超出范围,这将导致内存泄漏。例如:</p>
<pre><code>struct Node {
int val;
std::shared_ptr<Node> next;
};
a = make_shared<Node>(); // ref count 1
b = make_shared<Node>();
a.next = std::shared_ptr<Node>(b);
b.next = std::shared_ptr<Node>(a); // ref count 2!
</code></pre>
<p>地狱来了:即使a和b都超出范围,ref计数仍然是1,共享指针永远不会删除它们的对象,没有循环引用通常会发生什么。程序员必须明确地处理这个问题并打破循环(并禁止它发生)。例如,<code>b.next = make_shared<Node>();</code>在b超出范围之前就足够了。在</p>