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

C++ 将成员函数存储在向量中并确保对象在以后调用时仍然存在,c++,c++11,callback,std-function,object-lifetime,C++,C++11,Callback,Std Function,Object Lifetime,我有一个类X,我想把一个成员函数bar传递给另一个类Y,它将把它存储在一个向量中,并在其他时间调用它 我知道我需要确保X在Y调用函数时仍然存在。我该怎么做 在我下面的示例中,我最初认为如果我将共享的ptr传递给bar,这将实现我想要的功能-即只要Y存在,那么X也会存在,因为Y将共享的ptr保存到它的一个成员函数 我现在很确定这个逻辑是错误的。有人能告诉我吗 class Y { std::vector<std::shared_ptr<std::function<void()&

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

我知道我需要确保
X
Y
调用函数时仍然存在。我该怎么做

在我下面的示例中,我最初认为如果我将共享的ptr传递给
bar
,这将实现我想要的功能-即只要
Y
存在,那么
X
也会存在,因为
Y
将共享的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
  }
};
Y类{
std::向量m_v;
公众:
void foo(const std::shared_ptr&callback){
m_v.推回(回调);
}
有时无效{
//在vector中调用回调函数
//如何确保要调用函数的对象仍然存在
}
};
X类{
Y&m_Y;
公众:
X(Y&Y):m_Y(Y){
m_y.foo(std::make_shared(std::bind(&X::bar,this));
}
空条(){
//做点什么
}
};

下面是一个使用
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();
}
#包括
#包括
#包括
#包括
Y类{
std::向量m_v;
公众:
void foo(const std::shared_ptr&callback){
m_v.推回(回调);
}
有时无效{
用于(常数自动和f:m_v){
(*f)();
}
}
};
类X:public std::从\u中启用\u共享\u{
Y&m_Y;
std::函数m_回调;
公众:
X(Y&Y):m_Y(Y),m_回调(std::bind(&X::bar,this)){
}
void add()
{
m_y.foo(std::shared_ptr{shared_from_this(),&m_callback});

std::cout我最终改变了设计以解决我的终身问题

而不是按如下方式声明向量:

std::vector<std::shared_ptr<std::function<void()>>> 
std::vector
稍后对存储函数发出一个调用,我将其声明为:

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

然后在对象X上放置一个需求以实现一个命名函数(在我上面的示例中,它是
bar
)然后在适当的时候调用它。这样我就可以确保调用回调函数时X存在。

你不能使用比foo、bar、X和Y更具表现力的名称来让代码更可读,让想法更容易理解吗?你是对的,将
共享的ptr
保存到
std::function
,成员函数如果
X
已绑定,则对
X
实例的生存期没有任何影响。如果没有您最终尝试执行的操作的上下文,则建议解决方案有点困难。我认为
std::shared_ptr
的向量不会执行您想要的操作。您正在共享
std::function
而不是
X
的实例。您应该考虑一下
std::shared_ptr
在删除时将删除哪些内容。@A.S.H我认为这个想法很容易理解。问题很清楚。现在必须运行,但如果您以后需要,我会添加更多详细信息