将有效的 class 对象指针绑定到 boost::function<>fn。如果在对象被销毁后调用 `fn` 会发生什么?
Bind a valid class object pointer to boost::function<>fn. What may happen if invoking the `fn` after the object has been destoryed?
绑定一个 class 成员函数和一个有效的 class 对象指针到 boost::function<>fn。如果在指针指向的对象被销毁后调用 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的评论
One way to do that is to pass the object by value, not a pointer to the
object. Then a copy of the object would be used during the invocation
fn().
I think there is still a problem that the object 'tes' is out of scope.So passing value is not a good method.
:
#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.
}
您需要确保目标对象的生命周期超过函数对象的生命周期。使用 lambda 函数而不是绑定更容易以明显的方式表达。 lambda 可以显式捕获对象 'by-value':
std::function<int(void)> fn;
{
CTest tes;
fn = [tes] { tes.demo(); };
}
fn();
使用 std::bind 你也可以明确表达这一点,避免复制,写成:
fn = std::bind(&CTest::demo, std::move(tes));
您也可以按值而不是按引用传递给绑定,但我更喜欢上面的两种构造,因为它们使意图非常明确(复制对象或转移所有权)。
如果您想避免复制或转移所有权,您可以使用带有 lambda 的共享指针。您甚至可以在 lambda 中使用 weak_ptr
,因此该对象不会因此而保持活动状态。
另请参阅有关现代 C++ 中绑定和 lambda 的详细信息的非常有用的讨论:
绑定一个 class 成员函数和一个有效的 class 对象指针到 boost::function<>fn。如果在指针指向的对象被销毁后调用 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的评论
One way to do that is to pass the object by value, not a pointer to the object. Then a copy of the object would be used during the invocation fn(). I think there is still a problem that the object 'tes' is out of scope.So passing value is not a good method. :
#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.
}
您需要确保目标对象的生命周期超过函数对象的生命周期。使用 lambda 函数而不是绑定更容易以明显的方式表达。 lambda 可以显式捕获对象 'by-value':
std::function<int(void)> fn;
{
CTest tes;
fn = [tes] { tes.demo(); };
}
fn();
使用 std::bind 你也可以明确表达这一点,避免复制,写成:
fn = std::bind(&CTest::demo, std::move(tes));
您也可以按值而不是按引用传递给绑定,但我更喜欢上面的两种构造,因为它们使意图非常明确(复制对象或转移所有权)。
如果您想避免复制或转移所有权,您可以使用带有 lambda 的共享指针。您甚至可以在 lambda 中使用 weak_ptr
,因此该对象不会因此而保持活动状态。
另请参阅有关现代 C++ 中绑定和 lambda 的详细信息的非常有用的讨论: