将“this”作为shared_ptr引用?

6
我正在学习关于c++11的特性,特别是shared_ptr,并且在引用this并将其作为其他类的引用时遇到了问题。
这么做的原因是我有一个Simulation实例,它被传递给模拟中的其他实例(例如Apple),以便它们可以修改模拟,甚至从模拟中删除自己。
在我的更复杂的代码中,当程序退出时,我会得到double free错误(根据 from here,我应该不要在同一原始对象上两次创建shared_ptr)。当Simulation类不知道this已经是shared_ptr时,如何将this作为shared_ptr传递给Apple对象?
我的想法是在初始化参数中传递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;
}

你在哪里销毁 shared_ptr<Simulation> 实例? - Dai
2个回答

9
首先想到的是使用`enable_shared_from_this`:http://en.cppreference.com/w/cpp/memory/enable_shared_from_this 但第二个想法是,模拟应该管理苹果的生命周期,因此苹果不需要管理模拟的生命周期。因此,最好不要让苹果持有一个`shared_ptr` - 只有`main()`或一些高级函数应该管理模拟的生命周期。
如果不小心,你会得到循环引用。不要认为C++11中的每个指针都应该是shared_ptr。

最后一句话单独计分+1 - James

1
使用enable_shared_from_this,以便对象上的函数可以创建一个新的shared_ptr指向自己。您应该这样做,而不是创建第二个指向Simulationshared_ptrapple->init(std::shared_ptr<Simulation>(this));行。您还需要在某个地方返回或保存apple shared_ptr,因为目前Apple仅在initSomethingElse()运行时存在,这似乎并不是很有用...?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接