如何在C++中存储对其他对象的引用



这是我试图为C++最佳实践解决的一个更一般的问题。假设我想创建存储相互引用的对象,比如图。所有对象都归同一对象所有,就像所有节点的Graph对象一样,也就是说所有权是固定的。

我的想法是:Graph类有一个节点的std::vector,每个节点有一个表示其连接列表的节点的std::vector。我想知道如何在智能指针方面最好地实现这一点?据我所知,所有权是唯一的,所以Graph向量应该是std::vector<std::unique_ptr<Node>> nodes,我可以根据需要填充它。但是对于connections向量,如何让每个节点存储对其连接的引用?这些只是只读引用,也许最好命名所有节点并只存储名称,或者将连接存储在Graph中。但是有没有一种好的方法可以将对连接节点的引用存储为常量指针?

注意:这实际上是关于所有权和智能指针,而不是关于数据结构,图形示例只是一个示例。

当讨论"最佳实践";,重要的是要考虑代码的质量属性和需求。

不存在";右";或";错误的";在诸如Graph的代码的示例中回答;有不同程度的方法以不同的方式解决不同的问题,这在很大程度上取决于它的使用方式。

到目前为止,解决此类问题的最简单方法是主容器(Graph(在具有unique_ptr的中具有强所有权,并且仅使用原始指针(例如:(查看内部元素(Node(中的生存期

class Graph
{
...
private:
std::vector<std::unique_ptr<Node>> m_nodes;
};
class Node
{
...
private:
std::vector<const Node*> m_connected_nodes;
};

这将很好地工作,因为Node不能使其连接的节点发生突变,并且Graph假设Node永远不会超过它

但是如果您希望Node的寿命比Graph长,或者如果您希望在多个Graph对象中使用Node,则这种方法不起作用。如果它位于不同的Graph之间,那么您可能会遇到Node引用悬挂指针的风险——这将是糟糕的。

如果是这种情况,您可能需要考虑不同的所有权模式,例如shared_ptrweak_ptr所有权:


class Graph
{
...
private:
std::vector<std::shared_ptr<Node>> m_nodes;
};
class Node
{
...
private:
std::vector<std::weak_ptr<const Node*>> m_connected_nodes;
};

在这种情况下,Node只微弱地知道其他Node对象,而Graph是它们的强所有者。这防止了悬空问题,但现在shared_ptr的控制节点以及在访问weak_ptr节点之前必须检查其是否处于活动状态会带来额外的开销。

所以正确的答案是:这取决于。如果你能摆脱前一种方法,那可能是最干净的;您总是有一个所有者,因此逻辑简单易用。

我想知道如何在智能指针方面最好地实现这一点?

不使用它们。为图形使用节点向量:std::vector<Node>。这是一个合理的默认选择,除非你有充分的理由这样做。

但是有没有一种好的方法可以将对连接节点的引用存储为常量指针?

是。Const指针是一种很好的存储方式,就好像它们是Const指针一样。(通过"const指针",我想我们实际上是在谈论指针到const(。

引用包装器是另一种选择。尽管它的优点是没有null的表示,但它也有语法笨拙的缺点。

相关内容

  • 没有找到相关文章

最新更新