将成员函数存储在向量中并确保稍后调用时对象仍然存在

Storing member function in a vector and ensuring object still exists when invoked later

我有一个 class X 并且我想将一个成员函数 bar 传递给另一个 class Y,它将把它存储在一个矢量并在其他时间调用它。

我明白我需要确保 XY 调用函数时仍然存在。我该怎么做?

在我下面的示例中,我 最初 认为如果我将 shared_ptr 传递给 bar 这会做我想要的 - 即只要Y 存在,那么 X 也会存在,因为 Y 对其成员函数之一持有 shared_ptr。

现在我很确定这个逻辑是不正确的。谁能赐教一下吗?

class Y {
  std::vector<std::shared_ptr<std::function<void()>>> m_v;
public:
  void foo(const std::shared_ptr<std::function<void()>>& callback) {
    m_v.push_back(callback);
  }

  void sometime_later() {
    // invoke call back function in vector
    // how do I ensure the object I want to call the function on still exists
  }
};

class X {
  Y& m_y;
public:
  X(Y& y) : m_y(y) {
    m_y.foo(std::make_shared<std::function<void()>>(std::bind(&X::bar, this)));
  }

  void bar() {
    // do some stuff
  }
};

这里是使用 std::enable_shared_from_this 结合 shared_ptr 的别名构造函数的实现:

#include <vector>
#include <iostream>
#include <memory>
#include <functional>

class Y {
    std::vector<std::shared_ptr<std::function<void()>>> m_v;
public:
    void foo(const std::shared_ptr<std::function<void()>>& callback) {
      m_v.push_back(callback);
    }

    void sometime_later(){
        for (const auto& f: m_v) {
            (*f)();
        }
    }
};

class X : public std::enable_shared_from_this<X> {
  Y& m_y;
  std::function<void()> m_callback;
public:
  X(Y& y) : m_y(y), m_callback(std::bind(&X::bar, this)) {
  }

  void add()
  {
    m_y.foo(std::shared_ptr<std::function<void()>>{shared_from_this(), &m_callback});
    std::cout << shared_from_this().use_count() << "\n";
  }

  void bar() {
      std::cout << shared_from_this().use_count();
  }
};
int main(){

    Y y;
    {
        auto x = std::make_shared<X>(y);
        x->add();
    }
    y.sometime_later();
}

LIVE

我最终改变了设计来解决我一生的问题。

而不是像下面这样声明一个向量:

std::vector<std::shared_ptr<std::function<void()>>> 

稍后对存储的函数发出调用,我将其声明为:

std::vector<std::shared_ptr<X>> 

然后对对象 X 提出要求以实现命名函数(在我上面的示例中它应该是 bar),然后在适当的时间调用它。这样我就可以确保在调用回调函数时 X 存在。