C++ 如何通过传递“this”关键字来分配弱_ptr?

C++ 如何通过传递“this”关键字来分配弱_ptr?,c++,this,weak-ptr,C++,This,Weak Ptr,在我的项目中,小组将共享指向主题的指针;受试者会对他们的小组有弱点。我希望组有一个连接函数,它将主体的弱指针分配给自身。下面是我尝试过的最基本的代码。如何修复连接函数 #include <iostream> #include <string> #include <memory> class Party; class Subject { public: std::weak_ptr<Party> MyParty; }; class Par

在我的项目中,小组将共享指向主题的指针;受试者会对他们的小组有弱点。我希望组有一个连接函数,它将主体的弱指针分配给自身。下面是我尝试过的最基本的代码。如何修复连接函数

#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;
}
程序打印出来我没有派对。如果作业成功,它应该打印出“我在蓝队”。

行主题->MyParty=std::make_shared*this;创建一个新的Party对象,该对象是*this的副本,由临时std::shared\u ptr管理。subject->MyParty是从临时共享的\u ptr中分配的,但弱\u ptr不会使它们指向的对象保持活动状态。该语句完成后,make_shared返回的临时共享\u ptr将被销毁,并获取它所管理的Party对象。主题->我的派对现在没有指向任何东西

解决方案是使用:

不幸的是,这使得std::make_shared更难使用。有关该问题的更多信息,请参阅行subject->MyParty=std::make_shared*this;创建一个新的Party对象,该对象是*this的副本,由临时std::shared\u ptr管理。subject->MyParty是从临时共享的\u ptr中分配的,但弱\u ptr不会使它们指向的对象保持活动状态。该语句完成后,make_shared返回的临时共享\u ptr将被销毁,并获取它所管理的Party对象。主题->我的派对现在没有指向任何东西

解决方案是使用:


不幸的是,这使得std::make_shared更难使用。有关该问题的更多信息,请参见。

您似乎正在寻找。问题在于,该方没有自我意识到它总是由共享的ptr拥有。这不一定是坏事。一种选择是将要加入方的共享\u ptr传递给一个静态类函数。这似乎是您正在寻找的。问题是该方没有自我意识到它总是属于共享\u ptr。这不一定是坏事。一种选择是将加入方的共享\u ptr传递给一个静态类函数。std::enable_shared_from_的危险在于,现在参与方实例自我意识到它们属于共享\u ptr。如果在堆栈上创建了一个参与方,但它不是一个共享的\u ptr,并且它的使用方式恰好使某些东西试图获取一个共享的\u ptr或弱的\u ptr,这可能是一个问题,这将在UB land中着陆。为了防止这种情况发生,请使用返回共享\u ptr的工厂函数,并使用标记键使构造函数无法访问,因为您仍然希望使\u共享工作。@Eljay添加了一节讨论该问题。std::enable_shared_from_的危险在于,现在参与方实例自我意识到它们属于共享\u ptr。如果在堆栈上创建了一个参与方,但它不是一个共享的\u ptr,并且它的使用方式恰好使某些东西试图获取一个共享的\u ptr或弱的\u ptr,这可能是一个问题,这将在UB land中着陆。为了防止出现这种情况,请使用一个返回共享\u ptr的工厂函数,并使用标记键使构造函数无法访问,因为您仍然希望使\u shared正常工作。@Eljay添加了一节讨论这个问题。
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();
    }
};
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;
};