将有效的 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 的详细信息的非常有用的讨论: