C++ 现代C++;对象关系
我使用C++ 现代C++;对象关系,c++,oop,object,smart-pointers,C++,Oop,Object,Smart Pointers,我使用struct节点和struct边实现了一个图,其中: 每个边都有一个开始和一个结束节点 每个节点维护从其开始或结束的边对象列表 以下是一种可能的实施方式: 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; }; 虽然上面的结
struct节点和struct边实现了一个图,其中:
- 每个
边
都有一个开始和一个结束节点
- 每个
节点
维护从其开始或结束的边
对象列表
以下是一种可能的实施方式:
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++”的方式来实现它,同时满足以下要求:
避免使用指针
对于节点::边
能够存储标准C++容器 中的<代码>节点<代码>和<代码>边缘>代码>对象
<>这是如何在现代C++中完成的?所有的1-3都能实现吗
通过使用std::shared\u ptr或std::unique\u ptr
我认为向量在这里不是一个正确的选择,因为一个图通常不是线性的(通常来说,在大多数情况下,你不能像用堆那样线性化它)
没有标准的“通用”容器,但您可以在此处使用模板来实现通用性
例如,您的元素类可以如下所示:
template <class T>
struct Elem {
std::shared_ptr<Node> st , en;
T some_data;
};
模板
结构元素{
std::共享ptr st,en;
T一些_数据;
};
关于现代C++,我认为这里不鼓励结构,你应该封装你的数据< /p>
避免使用指针
您可以为此使用std::shared_ptr
和std::weak_ptr
。只需确定节点是否拥有边,反之亦然。非所有者类型应使用弱\u ptr
(以避免循环)
除非您的图是非循环的,否则您可能仍然需要注意所有权周期
std::unique_ptr
不是选项,因为节点和边之间没有一对一的关系,所以任何给定对象都不能有唯一的所有者
对节点::边使用std::向量
没问题。将其设置为std::vector
或std::vector
(取决于边是否拥有节点,反之亦然)
能够在标准C++容器中存储节点和边缘对象
没问题,只要确保您的类型可以安全地移动/复制,而不会泄漏或损坏内存,即具有正确的复制/移动构造函数和赋值运算符。如果你使用智能指针和代码> STD::向量< /代码>,这将自动发生。如 < P>现代C++避免将动态内存分配给原始指针。这是因为很容易忘记删除所说的指针。尽管如此,使用原始指针作为对象的引用并没有错,但前提是您可以保证对象的生存期将大于使用所述指针的时间
这些规则一般是:
如果对象只有一个所有者,请使用std::unique_ptr
使用原始指针引用在1中创建的对象。前提是您可以保证对象的生存期大于引用的使用期
对引用计数对象使用std::shared_ptr
当您不想增加引用计数时,使用std::weak_ptr
引用引用计数的对象
因此,在您的情况下,如果边缘
拥有节点
s,则使用std::unique\u ptr
,如果没有,则保留原始指针。
在您的节点
类中,如果节点
拥有边
请使用std::vector
否则请使用std::vector
,尽管将边
链接到它们自己的入侵链接列表中可能更有效
在复杂图形上做了一些工作后,可能需要在图形外部的向量中分配所有节点和边,然后仅使用图形内部的原始指针在内部引用它们。记住内存分配很慢,所以你做的越少,你的算法就会越快顺便说一下,这看起来更像是一个链表,所以你应该考虑<代码> STD::List< <代码>,而不是<代码> STD::vector < /代码> .@ NeXT,为什么?将边插入节点列表的起始位置还是中间位置?是否合并或拼接边缘列表?链表看起来像什么?@Cyber对于我的特殊情况,我不需要快速插入。所以,std::list
和std::vector
为我计算出同样的结果。避免使用“裸”或“原始”指针,因为“智能”指针(如std::shared_ptr、std::weak_ptr等)在概念上仍然是指针。unique_ptr
很难正确,因为每个边都由两个节点“拥有”,或者每个节点都可以由多个边“拥有”std::vector
是通用容器,除非您需要另一个容器的元素稳定性/迭代器无效规则,否则应首选它。模板是否适合解决此问题?他想处理几个类,而不是抽象这些类将包含的类型。一条边正好与两个节点相关联,因此不能在单个节点内通过值存储在std::vector
。类似地,可以将多条边与给定节点关联,因此不能让所有这些边都拥有std::unique\u ptr
。如果节点拥有边,反之亦然,则可以使用shared_ptr
和weak_ptr
管理图形外部的所有所有权。