首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >现代C++对象关系

现代C++对象关系
EN

Stack Overflow用户
提问于 2015-03-04 12:53:54
回答 3查看 857关注 0票数 2

我有一个使用struct Nodestruct Edge实现的图,其中:

  • 每个Edge都有一个开始和一个结束Node
  • 每个Node都维护一个Edge对象列表,这些对象从它开始或结束。

以下是一项可能的实施:

代码语言:javascript
复制
struct Node;

struct Edge {
  Node *st;
  Node *en;
  int some_data;
};

const int MAX_EDGES = 100;
struct Node {
  Edge *edges[MAX_EDGES];
  int some_data;
};

虽然上面的结构可以表示我心目中的图形,但我想以“现代C++”的方式来实现它,同时满足以下要求:

  1. 避免指针
  2. 使用std::vector表示Node::edges
  3. 能够将NodeEdge对象存储在标准的C++容器中

现代C++是如何做到这一点的?1-3都能实现吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-04 13:04:54

  1. 避免指针

为此,您可以使用std::shared_ptrstd::weak_ptr。只需决定是否希望节点拥有边缘,反之亦然。非拥有类型应该使用weak_ptr (以避免循环)。

除非您的图是无循环的,否则您可能仍然需要小心所有权周期。

std::unique_ptr不是一个选项,因为节点和边之间没有一对一的关系,因此不能有任何给定对象的唯一所有者。

  1. 使用std::向量表示节点::边

没问题。将其设置为std::vector<std::weak_ptr<Edge>>std::vector<std::shared_ptr<Edge>> (取决于边缘是否拥有节点,反之亦然)

  1. 能够在标准C++容器中存储节点和边缘对象

没有问题,只需确保您的类型可以安全地移动/复制,而不会泄漏或损坏内存,即具有正确的复制/移动构造函数和赋值运算符。如果您按照上面的建议使用智能指针和std::vector,这将自动发生。

票数 8
EN

Stack Overflow用户

发布于 2015-03-04 13:17:10

现代C++避免将动态内存分配给原始指针。这是因为很容易忘记删除所述指针。尽管如此,使用原始指针作为对对象的引用并没有什么问题,前提是您可以保证对象的生存期将大于使用所述指针。

这些规则一般是:

  1. 如果对象只有一个所有者,则使用std::unique_ptr
  2. 使用1中创建的引用对象的原始指针,前提是可以保证该对象的生存期大于使用引用的时间。
  3. 使用std::shared_ptr作为参考计数对象
  4. 当您不想增加引用计数时,使用std::weak_ptr引用引用计数。

因此,在您的示例中,如果Edge拥有Nodes,则使用std::unique_ptr,如果没有,则保留原始指针。在您的Node类中,如果Node拥有Edges,则使用std::vector<Edge>,否则使用std::vector<Edge*>,尽管在它们自己的入侵链接列表中将Edges链接在一起可能更有效。

在对复杂图做了一些工作之后,可以将所有的NodeEdgees分配到图外的向量中,然后只使用图中的原始指针在内部引用它们。记住,内存分配是缓慢的,所以你做的越少,你的算法就会越快。

票数 1
EN

Stack Overflow用户

发布于 2015-03-04 13:03:55

  1. 使用std::shared_ptr或std::unique_ptr
  2. 我不认为向量是正确的选择,因为一个图通常不是线性的(通常来说,在大多数情况下,你不能像堆一样线性化它)
  3. 没有标准的“通用-使用”容器,但您可以在这里使用模板作为泛型。

例如,元素类可以如下所示:

代码语言:javascript
复制
template <class T>
struct Elem {
  std::shared_ptr<Node> st , en;
  T some_data;
};

说到现代的C++,我认为这里不鼓励结构化,你应该封装你的数据

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28855056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档