[英]Bind a valid class object pointer to boost::function<>fn. What may happen if invoking the `fn` after the object has been destoryed?
绑定一个 class 成员 function 和一个有效的 class ZA8CFDE6331BD59EB2AC96F8911C4B66Z 指针到 boost:<fn666. 如果在指针指向的 object 被破坏之后调用fn
会发生什么? 是否有一些我应该注意的潜在问题? Domo 代码快照:
class CTest
{
public:
int demo(void){}
};
int main()
{
boost::function<int(void)> fn;
{
CTest ins;
fn = boost::bind(&CTest::demo, &ins);
}
fn();
}
已编辑( https://godbolt.org/z/r8EK1G )
引用自 j6t 的评论
一种方法是按值传递 object,而不是指向 object 的指针。 然后在调用 fn() 期间将使用 object 的副本。 我认为 object 'tes' 超出 scope 仍然存在问题。因此传递值不是一个好方法。 :
#include<functional>
#include<iostream>
class CTest
{
public:
int demo(void){std::cout << "do better" << std::endl;return 0;}
};
template <class T=CTest>
std::function<int(void)> bindWarp(T obj, int (T::*mem_func)(void))
{
return std::bind(mem_func, obj);
}
int main()
{
std::function<int(void)> fn;
{
CTest tes;
fn = bindWarp(tes, &CTest::demo);
}
fn(); //I think there is still a problem that the object 'tes' is out of scope.So passing value is not a good method.
}
您需要确保目标对象的生命周期超过 function 对象的生命周期。 使用 lambda function 而不是 bind,这更容易以明显的方式表达。 lambda 可以显式捕获 object “按值”:
std::function<int(void)> fn;
{
CTest tes;
fn = [tes] { tes.demo(); };
}
fn();
使用 std::bind 您还可以通过以下方式明确表达这一点,并避免复制:
fn = std::bind(&CTest::demo, std::move(tes));
您也可以通过按值而不是按引用来绑定,但我更喜欢上面的两个构造,因为它们的意图非常明确(复制 object 或转移所有权)。
如果您想避免复制或转让所有权,您可以使用 lambda 的共享指针。 您甚至可以在 lambda 中使用weak_ptr
,go,因此 object 不会为它保持活动状态。
另请参阅有关现代 C++ 中绑定和 lambda 的详细信息的非常有用的讨论: https://stackoverflow.com/a/17545183/21974
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.