C++ 是否可以检测绑定成员函数引用的对象是否被删除或销毁
我正在探索使用C++ 是否可以检测绑定成员函数引用的对象是否被删除或销毁,c++,function,pointers,bind,C++,Function,Pointers,Bind,我正在探索使用std::function和std::bind。我看到您可以绑定一个成员函数,例如: class A{ int c_ = 10; public: int add(int a, int b){ return a + b + c_; } }; int main(){ A* p_a = new A; std::function<int()> f = std::bind(&A::add, p_a, 1, 1);
std::function
和std::bind
。我看到您可以绑定一个成员函数,例如:
class A{
int c_ = 10;
public:
int add(int a, int b){
return a + b + c_;
}
};
int main(){
A* p_a = new A;
std::function<int()> f = std::bind(&A::add, p_a, 1, 1);
printf("%i\n", f()); // yields "12" (1 + 1 + 10)
delete p_a;
printf("%i\n", f()); // yields derpy numbers, no errors thrown.
}
A类{
int c_=10;
公众:
整数相加(整数a,整数b){
返回a+b+c;
}
};
int main(){
A*p_A=新的A;
函数f=std::bind(&A::add,p_A,1,1);
printf(“%i\n”,f());//产生“12”(1+1+10)
删除p_a;
printf(“%i\n”,f());//生成derpy数字,没有抛出错误。
}
有没有办法检测p_a是否已被删除
我的解决方案是使用一个保存函数的包装器类和对象的
弱ptr
。我只是想知道是否有更优雅的方法来实现这一点。std::bind
可以接受智能指针,因此您只需将std::shared\u ptr
传递给它即可
std::shared_ptr<A> p_a(new A);
std::function<int()> f = std::bind(&A::add, p_a, 1, 1);
std::共享ptr p_a(新a);
函数f=std::bind(&A::add,p_A,1,1);
请注意,函子将拥有该对象:该对象将一直存在。如果您不希望出现这种行为,那么使用弱\u ptr
包装器的解决方案很好
struct A{
int c_ = 10;
int add(int a, int b){
return a + b + c_;
}
};
template<class T>
std::weak_ptr<T> weak( std::shared_ptr<T> const& sp ) { return {sp}; }
int main(){
auto p_a = std::make_shared<A>();
std::function<int()> f = [w_a = weak(p_a)]() {
if (auto p_a = w_a.lock())
return p_a->add(1,1);
throw w_a;
}
printf("%i\n", f()); // yields "12" (1 + 1 + 10)
p_a.reset();
try {
printf("%i\n", f()); // yields derpy numbers, no errors thrown.
} catch( std::weak_ptr<A> wp ) {
printf("object deleted\n");
}
}
继承自的has_life
将为您提供一个get_life()
成员,该成员将在您执行此操作时一直存在(它将被析构函数销毁,并且不再是.lock()
d)
如果不能修改原始类的所有权语义,那么这是一种更容易遵循的模式。只需
.lock()
对象的生命周期标记
,即可确定其是否仍然处于活动状态。您可以使用智能指针(而不是原始指针),特别是:std::shared_ptr
和std::weak_ptr
。无法检测指针何时被删除。您应该避免创建对象不知道它想要访问的其他对象是否仍然处于活动状态的情况。智能指针是这里的方法。@πάνταῥεῖ 因此只要std::function
存在,对象就会存在?@MichaelMitchell我的想法是std::weak\u ptr
用于std::bind()
,您可以在调用f()
之前检查它。当然,您也可以绑定shared\u ptr
,它将保证A
的生命周期不早于f
在范围内结束。因此,如果std::bind
被传递shared\u ptr
只要函数存在,shared\u ptr
中的对象就不会被删除?你的编辑回答了这个问题。根据我的包装器类想法,如果我想让一个类绑定它的一个函数,我是否必须从启用共享,以便向包装器传递适当的弱ptr
。这是this@MichaelMitchell中的共享\u的经典用例。如果在某些类方法中无法获得指向此的智能指针,则必须使用this
中的启用共享\u。请注意,如果绑定发生在类之外,则不必这样做。
using lifetime_token = std::weak_ptr<void>;
struct has_lifetime {
has_lifetime():token(std::make_shared<char>()) {}
has_lifetime(has_lifetime const&o):has_lifetime() {} // not default
lifetime_token get_lifetime() const {
return token;
}
private:
std::shared_ptr<void> token;
};