Строка subject->MyParty = std::make_shared<Party>(*this);
создает новый Party
объект, который является копией *this
и управляется временным std::shared_ptr
.subject->MyParty
получает назначение из этого временного shared_ptr
, но weak_ptr
s не сохраняет объекты, на которые они указывают, живыми.Как только этот оператор завершается, временный 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();
}
};
Пример
Чтобы использовать 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;
};
Пример
К сожалению, это затрудняет использование std::make_shared
.Для получения дополнительной информации по этому вопросу см. этот вопрос .