如何通过传递“ this”关键字来分配weak_ptr?

时间:2019-06-14 13:44:24

标签: c++ this weak-ptr

在我的程序中,组将共享指向主题的指针;主题对他们的组的指示力很弱。我希望该组具有一个join()函数,该函数将Subject的弱指针分配给它自己。以下是我尝试过的最小代码。如何修复join()函数?

#include <iostream>
#include <string>
#include <memory>

class Party;

class Subject
{
public:
    std::weak_ptr<Party> MyParty;
};

class Party
{
public:
    std::string Name;

    void join(std::shared_ptr<Subject> subject)
    {
        subject->MyParty = std::make_shared<Party>(*this); // <---- PROBLEM
    }
};

int main()
{
    auto& BlueParty = std::make_shared<Party>();
    BlueParty->Name = "Blue Party";

    auto& Jane = std::make_shared<Subject>();

    BlueParty->join(Jane);

    if (auto ptr = Jane->MyParty.lock())
    { 
        std::cout << "I am in " << ptr->Name << std::endl; 
    }

    else { std::cout << "I have no party." << std::endl; }

    return 0;
}

程序将打印出“我没有聚会”。如果分配成功,则应该打印出“我在蓝党中”。

1 个答案:

答案 0 :(得分:5)

subject->MyParty = std::make_shared<Party>(*this);行创建一个新的Party对象,该对象是*this的副本,并由一个临时std::shared_ptr管理。 subject->MyParty是从该临时shared_ptr中分配的,但是weak_ptr并没有使它们指向的对象保持活动状态。该语句完成后,由shared_ptr返回的临时make_shared被销毁,并使用它管理的Party对象。 subject->MyParty现在什么都没有。

解决方案是使用std::enable_shared_from_this

class Party : public std::enable_shared_from_this<Party>
{
public:
    std::string Name;

    void join(std::shared_ptr<Subject> subject)
    {
        subject->MyParty = shared_from_this();
    }
};

Example

要使用shared_from_this,对象必须std::shared_ptr拥有。在这种情况下,通常最好标记该类的构造函数private并使用工厂函数,该工厂函数将shared_ptr返回到新实例,以便该类型的对象不受不能偶然创建shared_ptr

class Party : public std::enable_shared_from_this<Party>
{
public:
    std::string Name;

    static std::shared_ptr<Party> create()
    {
        return std::shared_ptr<Party>{new Party()};
    }

    void join(std::shared_ptr<Subject> subject)
    {
        subject->MyParty = shared_from_this();
    }
private:
    Party() = default;
    Party(const Party&) = delete;
};

Example

可悲的是,这使std::make_shared难以使用。有关该问题的更多信息,请参见this question