【发布时间】:2020-12-13 08:39:34
【问题描述】:
绑定一个类成员函数和一个有效的类对象指针到 boost::functionfn。如果在指针指向的对象被销毁之后调用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的评论
一种方法是通过值传递对象,而不是指向 目的。然后在调用期间将使用对象的副本 fn()。 我认为仍然存在对象“tes”超出范围的问题。因此,传递值不是一个好方法。 :
#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.
}
【问题讨论】:
-
您的程序有未定义的行为。任何事情都有可能发生。
-
@j6t 你的意思是我必须保证调用
std::function对象时指针(指向一个对象)仍然有效? -
是的,当然。一种方法是按值传递对象,而不是指向对象的指针。然后将在调用
fn()期间使用对象的副本。 -
@j6t“按值传递对象”?不是参考吗?你的意思是这个()?我认为这段代码 sn-p 有同样的问题。 godbolt.org/z/r8EK1G。我将此代码 sn-p 更新到帖子中。
-
这与你可以用更简单的方式得到的奇怪行为相同,而无需使用 std::function。见this example;但正如其他人所说,您处于 UB 领域。在这种情况下,它“有效”是因为
demo函数不访问this,(至少,对于许多编译器来说,这可能是原因)。但这只是“任何事情都可能发生”,即使它有效
标签: c++ c++11 boost boost-function