简体   繁体   English

std :: function到对象的成员函数和对象的生命周期

[英]std::function to member function of object and lifetime of object

If i have an instance of std::function that is bound to a member function of an object instance and that object instance goes out of scope and is otherwise destroyed will my std::function object now be considered to be a bad pointer that will fail if called? 如果我有一个绑定到对象实例的成员函数的std::function实例,并且该对象实例超出范围而被破坏,那么我的std::function对象现在将被视为一个错误的指针如果打电话失败?

Example: 例:

int main(int argc,const char* argv){
    type* instance = new type();
    std::function<foo(bar)> func = std::bind(type::func,instance);
    delete instance;
    func(0);//is this an invalid call
}

Is there something in the standard that specifies what should happen? 标准中是否有某些内容指明应该发生什么? My hunch is that it will throw and exception because the object no longer exists 我的预感是它将抛出异常,因为该对象不再存在

EDIT: Does the standard specify what should happen? 编辑:标准是否指定应该发生什么?

Is it undefined behavior? 是不确定的行为?

EDIT 2: 编辑2:

#include <iostream>
#include <functional>
class foo{
public:
    void bar(int i){
        std::cout<<i<<std::endl;
    }
};

int main(int argc, const char * argv[]) {
    foo* bar = new foo();
    std::function<void(int)> f = std::bind(&foo::bar, bar,std::placeholders::_1);
    delete bar;
    f(0);//calling the dead objects function? Shouldn't this throw an exception?

    return 0;
}

Running this code i receive an output value of 0; 运行此代码我收到输出值0;

What will happen is undefined behavior. 会发生什么是未定义的行为。

The bind() call will return some object that contains a copy of instance , so that when you call func(0) will effectively call: bind()调用将返回一些包含instance副本的对象,这样当你调用func(0)会有效地调用:

(instance->*(&type::func))(0);

Dereferencing an invalid pointer, as you would do there if instance were delete d, is undefined behavior. 如果instancedelete d,则取消引用无效指针是未定义的行为。 It will not throw an exception (although, it's undefined, so it could, who knows). 它不会抛出异常(虽然,它是未定义的,所以它可以,谁知道)。

Note that you're missing a placeholder in your call: 请注意,您在通话中错过了占位符:

std::function<foo(bar)> func = 
    std::bind(type::func, instance, std::placeholders::_1);
//                                  ^^^^^^^ here ^^^^^^^^^

Without that, you can't call func(0) even with a non-deleted instance. 没有它,即使使用未删除的实例,也无法调用func(0)

Updating your example code to better illustrate what's going on: 更新示例代码以更好地说明正在发生的事情:

struct foo{
    int f;
    ~foo() { f = 0; }

    void bar(int i) {
        std::cout << i+f << std::endl;
    }
};

With that added destructor, you can see the difference between copying the pointer (in f ) and copying the object that was pointed to (in g ): 使用添加的析构函数,您可以看到复制指针(在f )和复制指向的对象(以g )之间的区别:

foo* bar = new foo{42};
std::function<void(int)> f = std::bind(&foo::bar, bar, std::placeholders::_1);
std::function<void(int)> g = std::bind(&foo::bar, *bar, std::placeholders::_1);
f(100); // prints 142
g(100); // prints 142
delete bar;
f(100); // prints 100
g(100); // prints 142 still, because it has a copy of
        // the object bar pointed to, rather than a copy
        // of the pointer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM