Search code examples
c++c++11callbackstd-functionobject-lifetime

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


I have a class X and I want to pass a member function bar to another class Y, which will store it in a vector and invoke it at some other time.

I understand that I need to make sure that X still exists when Y invokes the function. How do I do that?

In my example below, I initially thought that if I passed a shared_ptr to bar this would do what I want - i.e. as long as Y exists, then so will X, as Y holds a shared_ptr to one of its member functions.

I'm pretty sure now that this logic is incorrect. Can someone please enlighten me?

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
  }
};

Solution

  • I ended up changing the design to resolve my lifetime issue.

    Rather than declaring a vector as follows:

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

    and issuing a call on the stored function sometime later, I declare it as:

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

    and then place a requirement on the object X to implement a named function (in my example above it woyuld be bar) and then call it at the appropriate time. That way I ensure X exists when the callback function is invoked.