c++ - 当两个shared_pointer实例被删除时,删除由两个shared_pointer实例管理的对象

标签 c++ pointers

我有一个由 NodeEdge 类表示的有向图模型。每个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;
};

到目前为止,我已经使用这样的原始指针实现了它。它相当复杂,并且涉及在删除节点时从边缘的另一侧(对于每条边缘)手动删除指针。我宁愿使用智能指针来使其更加安全和干净。

然而,事实上我需要删除两侧的边缘(并使另一侧的指针无效),这使得它成为问题。如果我使用共享指针,则边缘永远不会被删除(即使另一侧消失,剩余的引用也将保持有效)。如果我使用弱指针,我又需要将共享指针存储在其他地方,这将再次变得更加复杂,因为每当任何一方被删除时我都需要查找它并删除它。

我需要的是一个“智能”指针,它将跟踪被指针(如共享指针),但当其内部计数器降至 1(而不是 0)时删除其被指针,从而使其自身失效(如弱指针)不超出范围。

我应该自己写还是有其他解决方案?

最佳答案

节点

每条边至少由两个节点引用。如果没有节点引用一条边,则该边无用,可以删除。这表明从节点到边的指针应该是 shared_ptr<Edge>

模型中的指针 vector 应该是 shared_ptr<Node>

边缘

只有源节点和目标节点存在时,边才能存在,但没有边的节点也可以存在。这表明边中指向节点的指针应该是 weak_ptr<Node> from, to ;

您可以随时检查 from 是否或to节点已被删除 from.expired() 。但是您无法找到删除边缘的正确方法:从两侧删除其指针,在这种情况下,当不再需要时会触发边缘的销毁。

关于c++ - 当两个shared_pointer实例被删除时,删除由两个shared_pointer实例管理的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35880154/

相关文章:

c++ - 我可以禁用 SFINAE 吗?

python - C++ 相当于 Python 字符串切片?

c++ - 在构造函数中设置 C++ 类 char*

c++ - 函数返回后如何删除堆分配的变量

C++11 线程 boost 容器

c++ - 如何在C++中的某个变量中存储日期

c++ - 了解 C++ 中指针的 const 正确性

c - 在C中传递非全局数组变量

c++ - 处理指针数组

c - 在 OpenCl 内核中使用指针