在构造函数中传递shared_ptr

Passing shared_ptr of this in constructor

本文关键字:shared ptr 构造函数      更新时间:2023-10-16

我有如下代码

class Task;
class Attribute
{
public:
    Attribute(Task* task, std::string name);
    std::shared_ptr<Task> task_;
    std::string name_;
};
class Task : std::enable_shared_from_this<Task>
{
public:
    std::shared_ptr<Task> getSharedPtr()
    {
        return this->shared_from_this();
    }
    Attribute att1_ = {this, "attribute1"};
    Attribute att2_ = {this, "attribute2"};
};
Attribute::Attribute(Task* task, std::string name)
    : name_(name)
{
   task_ = task->getSharedPtr();
}

当我运行它时,我得到一个

$ terminate called after throwing an instance of 'std::bad_weak_ptr'

从这个问题中,我得到的是,在对象完全构造之前,我不能调用shared_from_this()。我想这意味着我无法在构造函数中创建 Attribute 类型的对象,但我应该在构造函数结束后实例化它们。

你知道这是否是克服这个问题的一种方法吗,因为对我来说,必须实例化不在构造函数中的 Attribute 对象真的很烦人。

由于Task拥有Attribute,因此Attribute不需要与Task共享所有权 - 他们不必担心超过Task。您可以只使用原始指针:

class Attribute
{
public:
    Attribute(Task* task, std::string name);
    Task* task_;
    std::string name_;
};

或者,如果您想更明确地表达语义,observer_ptr<Task> .

请注意,您必须为Task使用复制/移动构造函数/赋值运算符,以正确重新分配属性以指向新Task而不是旧。

我认为你违反了这个规则,如下:

请注意,在对象 t 上调用 shared_from_this 之前,必须 成为拥有 T 的 std::shared_ptr。

你似乎在TaskAttribute之间有一种奇怪的所有权关系,你可能想重新考虑(如果一个Task拥有自己的Attributes,为什么他们需要shared_ptr他们的Task

>当我在 std::enable_shared_from_this 前面忘记"public"时,我遇到了同样的错误(在 mac 上)。