std :: function对象的成员函数和对象的生命周期 [英] std::function to member function of object and lifetime of object

查看:912
本文介绍了std :: function对象的成员函数和对象的生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个 std :: function 的实例绑定到对象实例的成员函数,并且该对象实例超出范围,否则将被销毁我的 std :: function 对象现在被认为是一个坏的指针,如果调用将失败?

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?

示例:

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

编辑:
标准是否指定应该发生什么?

Does the standard specify what should happen?

是否未定义行为?

编辑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;
}

运行此代码,我接收到输出值0;

Running this code i receive an output value of 0;

推荐答案

会发生什么是未定义的行为。

What will happen is undefined behavior.

bind()调用将返回包含 instance ,因此当你调用 func(0)将有效地调用:

The bind() call will return some object that contains a copy of instance, so that when you call func(0) will effectively call:

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

参照无效指针,就像 instance delete d,是未定义的行为。

Dereferencing an invalid pointer, as you would do there if instance were deleted, is undefined behavior. 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 ^^^^^^^^^

没有这个,你不能调用 func(0)即使有一个未删除的实例。

Without that, you can't call func(0) even with a non-deleted instance.

更新您的示例代码以更好地说明发生了什么:

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;
    }
};

使用添加的析构函数,可以看到复制指针> f )并复制指向的对象(在 g ):

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):

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

这篇关于std :: function对象的成员函数和对象的生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆