将成员函数存储在向量中并确保稍后调用时对象仍然存在
Storing member function in a vector and ensuring object still exists when invoked later
我有一个 class X
并且我想将一个成员函数 bar
传递给另一个 class Y
,它将把它存储在一个矢量并在其他时间调用它。
我明白我需要确保 X
在 Y
调用函数时仍然存在。我该怎么做?
在我下面的示例中,我 最初 认为如果我将 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();
}
我最终改变了设计来解决我一生的问题。
而不是像下面这样声明一个向量:
std::vector<std::shared_ptr<std::function<void()>>>
稍后对存储的函数发出调用,我将其声明为:
std::vector<std::shared_ptr<X>>
然后对对象 X 提出要求以实现命名函数(在我上面的示例中它应该是 bar
),然后在适当的时间调用它。这样我就可以确保在调用回调函数时 X 存在。
我有一个 class X
并且我想将一个成员函数 bar
传递给另一个 class Y
,它将把它存储在一个矢量并在其他时间调用它。
我明白我需要确保 X
在 Y
调用函数时仍然存在。我该怎么做?
在我下面的示例中,我 最初 认为如果我将 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();
}
我最终改变了设计来解决我一生的问题。
而不是像下面这样声明一个向量:
std::vector<std::shared_ptr<std::function<void()>>>
稍后对存储的函数发出调用,我将其声明为:
std::vector<std::shared_ptr<X>>
然后对对象 X 提出要求以实现命名函数(在我上面的示例中它应该是 bar
),然后在适当的时间调用它。这样我就可以确保在调用回调函数时 X 存在。