如何使用C 中的共享/弱指针清洁实现两个对象

How to cleanly implement two objects referring to eachother using shared/weak pointers in c++?

本文关键字:实现 对象 两个 清洁 指针 何使用 共享      更新时间:2023-10-16

假设我有一个类:

class Entity {
    vector<weak_ptr<Entity> > aboveMe;
    vector<weak_ptr<Entity> > belowMe;
    void addBelow(weak_ptr<Entity> below)
    {
        belowMe.push_back(below);
    }
    void addAbove(weak_ptr<Entity> above)
    {
        aboveMe.push_back(below);
    }
}

这必须始终是正确的:

If an Entity A is above an Entity B, B is below A and vice versa.

代表这一点的最优雅的方式是什么?

当前,客户端代码可以简单地致电:

a->addBelow(b).

但是,没有对

的相应调用
b->addAbove(a)

不变的侵犯!

在Java中,人们会做这样的事情:

void addBelow(Entity below)
{
    belowMe.add(below);
    below.addAbove(this); // With obviously some mechanism to prevent infinite recursion
}

使用共享/弱指针时在C 中执行此操作的最佳方法是什么?

您当然可以在C 中使用类似的方法。如果一个对象被设计为通过共享指针管理其寿命,则可以从模板类std::enable_shared_from_this继承,例如:

class Entity : public std::enable_shared_from_this<Entity> { ...

您可以从this指针安全地创建共享指针。然后方法:

void addBelow(weak_ptr<Entity> below)
{
    belowMe.push_back(below);
    below.addAbove(shared_from_this());
}

将接近您的需求。

在这里要指出的东西:正如链中的对象之间没有所有权关系,因此,这项工作提供了从外部"拥有"的对象。

如果您想允许所有权层次结构,则可以另外更改链条,以便对象"自有向下":

vector<weak_ptr<Entity> > aboveMe;
vector<shared_ptr<Entity> > belowMe;

注意:您当然不希望这两个方向共享指针,因为您将拥有循环所有权,因此永远不会发布对象。

注2:shared_ptr类可以从weak_ptr引用和反之亦然构造。无论您选择上述addBelow的所有权层次结构如何无效而无需修改。