我有一个由Node
和Edge
类表示的有向图模型。每个Node
对象都保存指向其所有传出和传入边的指针,每个Edge
对象保存指向其原点和结尾(Node
对象)的指针。
class Model
{
public:
~Model()
{
for(Node *node : nodes)
delete node;
}
QVector<Node*> nodes;
};
class Node
{
public:
~Node
{
for(Edge *edge : from)
{
if(edge)
{
edge->to->to.replace(edge, nullptr);
delete edge;
}
}
for(Edge *edge : to)
{
if(edge)
{
edge->from->from.replace(edge, nullptr);
delete edge;
}
}
}
QVector<Edge*> from;
QVector<Edge*> to;
};
class Edge
{
public:
Node *from;
Node *to;
};
到目前为止,我已经使用这样的原始指针实现了它。它相当复杂,并且当节点被删除时涉及从边缘的另一侧(对于每个边缘)手动移除指针。我宁愿使用智能指针使它更安全和更清洁。
然而,我需要为双方删除边缘(并使另一边的指针无效)这一事实使其成为问题。如果我使用共享指针,则边缘永远不会被删除(即使另一边消失,剩余的引用也将保持有效)。如果我使用弱指针,我反过来需要将共享指针存储在其他地方,这将再次变得更加复杂,因为我需要查找它并在任何一方被删除时摆脱它。
我需要的是一个&#34; smart&#34;指针将跟踪指针对象(如共享指针),但在其内部计数器降为1(而不是0)时删除其指针,以使其自身无效(如弱指针)而不会超出范围。
我应该自己写还是有其他解决方案?
答案 0 :(得分:1)
如果该实例被删除,您希望能够执行的操作是使Node
实例的所有指针无效。这意味着你想要一个自我所有权的概念。因此,指向Node
的所有指针都应该是指向由Model
(或者Node
本身)管理的共享指针的弱指针。
可以使每个Node
只有指向相邻节点的弱指针。 Edge
可以根据需要按需制作,而Edge
也只能包含弱指针。
答案 1 :(得分:1)
<强>节点强>
每个边缘至少由两个节点引用。如果没有节点引用边缘,则此边缘无用且可以删除。这表明从节点到边缘的指针应该是shared_ptr<Edge>
。
模型中的指针向量应该是shared_ptr<Node>
<强>边强>
仅当源节点和目标节点存在时,边缘才可存在,但节点可以不存在边缘。这表明节点边缘的指针应为weak_ptr<Node> from, to
;
您始终可以使用from.expired()
检查是否删除了from
或to
个节点。但是你没有办法绕过正确的方法来移除边缘:从两侧移除它的指针,在这种情况下,当不再需要时会触发边缘的破坏。