c++ - 调用指向已释放对象方法的 std::function 对象

标签 c++ c++11 function-pointers std

考虑这段代码:

#include <iostream>
#include <functional>

using namespace std;
using namespace std::placeholders; 

typedef function<void(const int&)> SomeFunc;

class X {
public:
    X(string name):name_(name)
    { cout << "ctor " << name_ << endl; }

    ~X()
    {
        cout << "dtor " << name_ << endl; 
        name_ = "empty";
    }

    SomeFunc
    getSomeFunc()
    { return bind(&X::someMethod, this, _1); }

private:
    string name_;

    void
    someMethod(const int& a)
    {
        cout << name_ << " some method with " << a << endl;
    }
};


int main()
{
    SomeFunc f;

    {
        shared_ptr<X> x(new X("Object"));
        f = x->getSomeFunc();
        f(1);
    }

    f(2);

    return 0;
}

有时,输出会给我这个:

ctor Object
Object some method with 1
dtor Object
empty some method with 2

其他时候:

ctor Object
Object some method with 1
dtor Object
 some method with 2

在现实世界中,一旦释放的对象尝试访问它的属性,它很可能会让我崩溃。 所以这里有一个问题 - 由于函数不能保证保留对其所指向的对象的引用,因此在引用的对象已被释放后调用函数时避免崩溃的最佳实践是什么?

我可能想到的解决方案之一 - 在对象内部维护一个特殊的标志 bool deallocated_ ,并在释放后可能调用的方法内部检查它。不过,我怀疑它也不可靠。

更新(来自评论):

我需要这个解决方法的真正原因是该库将函数作为参数。该库异步运行,我无法控制传递给它的函数对象。这就是为什么当我的对象被释放时,库仍然可以使用最初传递的函数调用回调,从而导致崩溃。

最佳答案

您的对象由 shared_ptr 持有,因此您可以使用 lambda 来关闭 shared_ptr:

auto func = [ptr](const int &p){ ptr->someMethod(p); };

您需要使用 shared_from_this 在类中获取 ptr

这是一个完整的示例:

#include <iostream>
#include <functional>
#include <memory>

using namespace std;
using namespace std::placeholders; 

typedef function<void(const int&)> SomeFunc;

class X : public enable_shared_from_this<X> {
public:
    X(string name) : name_(name) {
        cout << "ctor " << name_ << endl;
    }

    ~X() {
        cout << "dtor " << name_ << endl; 
        name_ = "empty";
    }

    SomeFunc getSomeFunc() {
        auto ptr = shared_from_this();
        return [ptr](const int &a){ ptr->someMethod(a); };
    }

private:
    string name_;

    void someMethod(const int& a) {
        cout << name_ << " some method with " << a << endl;
    }
};


int main()
{
    SomeFunc f;

    {
        shared_ptr<X> x(new X("Object"));
        f = x->getSomeFunc();
        f(1);
    }

    f(2);

    return 0;
}

输出如下所示:

ctor Object
Object some method with 1
Object some method with 2
dtor Object

关于c++ - 调用指向已释放对象方法的 std::function 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28080183/

相关文章:

c++ - socket Recv api 返回意外值

multithreading - 使用 std::future 从函数返回多个值

javascript - 调用V8函数导致访问冲突

C++\CLI LNK Error 2019 & 2028 with Included .h and .lib (Linker finds those Files) [Wrapper]

c++ - 在 Windows 上编译 C++ (Mingw/Cygwin)

C++11 可变参数 std::function 参数

c++ - 使用函数指针显示函数的返回值

rust - 什么时候应该使用函数指针而不是闭包?

C++ 指向其他类函数的指针函数

c++ - 哪些模拟框架允许对遗留代码进行零更改?