代码之家  ›  专栏  ›  技术社区  ›  happy_sisyphus

如果存在循环关系,我应该假设使用弱指针吗?[关闭]

  •  3
  • happy_sisyphus  · 技术社区  · 6 年前

    说我有一个 Person 类,与 name , age bestFriend 作为属性。我对如何最好地表现感到困惑 最好的朋友 . 倍数 实例可以指向同一个 最好的朋友 排除了 unique_ptr . 还有一个循环关系的可能性,它排除了 shared_ptr . 所以,就是使用 weak_ptr 在这种情况下是理想的?我想在这里使用智能指针而不是原始指针吗?

    class Person {
        std::string name;
        int age;
        std::weak_ptr<Person> bestFriend;
    };
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   Mikhail    6 年前

    指针(原始和智能)表示 所有权 . 因此,要选择合适的指针,您需要决定所有权。如果某事 拥有 一个物体,如果这个东西死了,这个物体也必须死。如果我死了,我最好的朋友会死吗?我不这么认为。因此,我没有 拥有 我最好的朋友。这排除了 unique_ptr shared_ptr ,因为它们是 拥有 智能指针。

    所以我们有两个选择: weak_ptr 或原始指针。这取决于你如何跟踪活着的人。

    最简单的方法可能是依靠智能指针来跟踪活着的人。这意味着,你有一些 SelddPPTR 给所有人,然后你储存 弱者PTR 从另一个人那里指向他们。在这种情况下,我知道如果我有一个朋友 weak_ptr::lock() 收益率 nullptr ,这意味着我的朋友死了。方便,但不是很灵活。例如,假设你需要在一个人死后给一个家庭发一封信。你什么时候会这样做?在人的毁灭者身上?这是责任的混合。在自定义删除程序中 shared_ptr<Person> ?这将破坏封装,因为这个自定义删除程序可能有许多函数。

    另一种方法是由一个专门的经理来跟踪活着的人。同样,你需要一个所有人居住的地方。您可以按值存储它们,或通过 SelddPPTR -由你决定。然后存储指向这些对象的原始指针。(注意:如果您将它们存储在一个向量中,这个向量的大小是一个要更改的对象,那么存储指向它们的原始指针是不明智的,因为可能会重新分配)。在这种情况下,你不能通过看一个原始指针来判断我最好的朋友是否还活着。我们需要检查经理以获得这些信息。这是更灵活的,但我会说不太安全,因为我们的系统中内置了悬空指针。

    我建议不要为了这个目的而存储原始指针,而是去获取一个ID。相反,存储个人ID,并按ID拥有一个个人注册中心。这个注册中心将处理所有的混乱,并将正确地检测情况,当有人想要访问一个死人时,触发一个邮递员给亲属发一封信,等等。这也允许区分当我没有最好的朋友,当我最好的朋友死了。 弱者PTR 会回来 努尔普特 在这两种情况下。

    如果我们储存 SelddPPTR 对最好的朋友来说,这意味着一个人只要是他最好的朋友就可以活着…所以是真的,但在软件开发领域不是,对不起。

        2
  •  2
  •   Walter    6 年前

    智能指针 std::unique_ptr<> std::shared_ptr<> 用于 unique or shared ownership 指向的对象。在你的情况下 Person 这一所有权概念几乎没有意义,最好的朋友大概最好用一个简单的原始(观察)指针来表示:

    struct Person
    {
        std::string name;
        date_type born, died=date_type::never;
        const Person *bestFriend = nullptr;     // defaults to none
    
        time_type age() const
        { died==date_type::never? date_type::today()-born : 0; }
    };
    

    尽管如此,您必须确保这些指针始终有效。为此, 可以使用 std::deque<Person> 允许添加新的 S W/O使任何现有的 指针。但是,不能删除任意 没有无效的指向其他的指针 S,所以最好标记A 因为你死了而不是把它移走 指针)。这样做的好处是可以避免挂起“最好的朋友”指针(但你会得到死去的最好的朋友)。

    警告。 因为你没有提供更多关于 class Person 以上建议是基于一些推测,根据您的实际意图,可能实际上并不有用。