c++ - 打破shared_ptr和unique_ptr之间的循环依赖

标签 c++ shared-ptr smart-pointers unique-ptr circular-dependency

鉴于此代码:

#include <iostream>
#include <memory>

class Controller;

class View {
public:
    ~View() {
        std::cout << "Disposing View" << std::endl;
    }

    void SetObserver(std::shared_ptr<Controller> a_observer) {
        observer = a_observer;
    }
private:
    std::shared_ptr<Controller> observer;
};

class Controller : public std::enable_shared_from_this<Controller> {
public:
    static std::shared_ptr<Controller> Create(std::unique_ptr<View> view) {
        //Can't use std::make_shared due to visibility rules :(
        auto controller = std::shared_ptr<Controller>(new Controller(std::move(view)));

        controller->Init();

        return controller;
    }

    ~Controller() {
        std::cout << "Disposing Controller" << std::endl;
    }
private:
    std::unique_ptr<View> view;

    explicit Controller(std::unique_ptr<View> a_view) : view(std::move(a_view)) {}

    Controller(const Controller&) = delete;

    void Init() {
        view->SetObserver(shared_from_this());
    }
};

int main() {
    auto view = std::make_unique<View>();

    auto controller = Controller::Create(std::move(view));

    return 0;
}

我认为 controller 对象永远不会被释放(由 running it 确认)。

为了缓解此问题,将 observer 变量设置为 weak_ptr 而不是 shared_ptr 是否足够?

除此之外,考虑到上述设计,我还应该注意其他潜在问题吗?

最佳答案

是的,正如您所说的 std::weak_ptr :

In addition, std::weak_ptr is used to break circular references of std::shared_ptr.

将成员更改为 std::weak_ptr 并运行,产生

$ ./a.out 
Disposing Controller
Disposing View

当你需要它时,只需调用lock(检查返回值),即可获取std::shared_ptr(你不应该这样做) > 作为成员(member)存储):

void doSomethingWithView() {
    auto obs = observer.lock();                                                                                                                                                                          
    if(obs) {
        // Still valid
    }   
}   

一个可能的警告与std::weak_ptr and multithreading有关。 .

关于c++ - 打破shared_ptr和unique_ptr之间的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35956295/

相关文章:

c++ - vector 迭代器不兼容

c++ - 在 C++ 中让一个类完成工作还是将一个类分成几个子类?

c++ - 如何简单地调整指针的集合或映射排序谓词

c++ - 通过类析构函数中重置成员shared_ptrs解决C++11shared_ptr循环引用?

c++ - 在智能指针容器中添加一个项目

c++ - 应该 std::auto_ptr<>::operator = 重置/取消分配其现有指针?

arrays - 在 Cython 中使用智能指针动态分配数组

C++从字符串到对象标识符的转换

c++ - 下面粗体的句子,在 Nicolai Josuttis 的书 "The Standard Library"中,我不清楚

c++ - 为什么这个 shared_ptr 在超出范围时抛出断言?