参考"这个"作为shared_ptr?

时间:2014-09-25 04:18:35

标签: c++ c++11 shared-ptr

我正在学习c ++ 11的功能,特别是shared_ptr,我在引用this并将其作为其他类的参考时遇到了问题。

这样做的原因是我有一个Simulation实例传递给模拟中的其他实例(例如Apple),因此他们可以自己修改模拟,甚至将自己从模拟中移除模拟。

在我更复杂的代码中,我得到double free错误(当程序存在时),据我所知from here我不应该在同一个原始对象上创建shared_ptr两次。当Simulation类不知道this已经是Apple时,如何将shared_ptr作为this对象传递给shared_ptr

我的想法是在初始化参数中传递shared_ptr,但这似乎是多余的,例如:

// The argument is a std::shared_ptr<Simulation>
simulation->initSomethingElse(simulation);

也许我试图以一种不寻常的模式实现这一点,或者我的理解可能不太正确?也许有一种更好的方法可以做到这一点?

我在下面有一个简化的例子:

#include <memory>

class Simulation;

class Apple {
public:
    void init(std::shared_ptr<Simulation> simulation) {
        this->simulation = simulation;
    };

private:
    std::shared_ptr<Simulation> simulation;

};


class Simulation {
public:
    void initSomethingElse() {
        auto apple = std::shared_ptr<Apple>(new Apple());

        // incorrect second reference to the raw pointer
        apple->init(std::shared_ptr<Simulation>(this));
    };
};


int main() {

    auto simulation = std::shared_ptr<Simulation>(new Simulation());
    simulation->initSomethingElse();

    return 0;
}

2 个答案:

答案 0 :(得分:8)

首先想到的是使用enable_shared_from_thishttp://en.cppreference.com/w/cpp/memory/enable_shared_from_this

但是我想到的第二件事是Simulation应该管理Apple的生命周期,因此Apple无需管理Simulation的生命周期。因此,最好不让Apple持有shared_ptr<Simulation> - 只有main()或某些高级功能才能管理模拟的生命周期。

如果您不小心,最终会得到循环引用。不要假设C ++ 11中的每个指针都应该是shared_ptr。

答案 1 :(得分:1)

使用enable_shared_from_this,这样对象上的函数就可以为自己创建一个新的shared_ptr。您将要执行此操作,而不是apple->init(std::shared_ptr<Simulation>(this));行,以便为shared_ptr创建第二个Simulation。您还希望在某处调整或保存apple shared_ptr,因为Apple仅在initSomethingElse()正在运行时存在,而不是{{1}}看起来很有用......?