首页 > 解决方案 > 回调函数向量和函数指针绑定

问题描述

我是新手,std::function正在尝试实现回调函数。在以下代码中,“Callback_t”包含一个函数,该函数包含要调用的函数向量。“other”类是“SomeClass”中的一个嵌套类。“SomeClass”的对象包含嵌套类对象“b”的数组。“其他”类构造函数将函数指针分配给“fptr”。我将此函数推入回调类“Callback_t”的向量中。当我运行此代码时,在调用向量中的第一个函数时出现分段错误。我无法弄清楚该声明有什么问题

this->loc_ptr->set_of_cb.push_back(this->b[i].fptr);

但是,如果我将其替换为

this->loc_ptr->set_of_cb.push_back(std::bind(&other::func, &(this->b[i])))

代码完美运行。我需要帮助来理解原始陈述有什么问题。

#include <functional>
#include <iostream>
#include <vector>
typedef std::function<void(void)> func_type;
class Callback_t {
public:
    std::vector<func_type> set_of_cb;
    void myCallback()
    {
        for (int i = 0; i < set_of_cb.size(); i ++){
                set_of_cb[i]();
        }
    }
};
class SomeClass;
class SomeClass {
private:
        Callback_t *loc_ptr;
        int a[10];
        class other{
                public:
                int id;
                SomeClass *loc;
                func_type fptr;
                other(){};
                other(SomeClass *loc, int id){
                        this->id = id;
                        this->loc =loc;
                        fptr = std::bind(&other::func,this);
                }
                void func(void){
                        this->loc->a[id] = loc->a[id] * id;
                        return;
                }
        };

public:
    other *b;

    //other b[10];
    SomeClass(Callback_t *a = nullptr){
        this->loc_ptr = a;
         this->b = new other[10];
        for(int i =0; i <10;i++){
                this->a[i] = i;
                this->b[i] = other(this, i);
                this->loc_ptr->set_of_cb.push_back(this->b[i].fptr);
        }
    }
    void read(void){
        for(int i =0; i <10;i++){
                std::cout<<a[i]<<std::endl;
        }
    }
};

int main()
{
    Callback_t *tmp;
    tmp = new Callback_t;
    SomeClass tmp1(tmp);
    tmp1.read();
    tmp->myCallback();
    tmp1.read();
    delete tmp;

}

标签: c++

解决方案


            other(SomeClass *loc, int id){
                    this->id = id;
                    this->loc =loc;
                    fptr = std::bind(&other::func,this);
            }

构造函数绑定fptrthis,这是构造的对象。现在,请注意:

  this->b[i] = other(this, i);

这将执行以下事件序列。这里发生了很多事情,这对这个谜团至关重要:

  1. 一个临时other对象被构造出来,它的构造函数做它所做的事情。请注意,该对象是临时的,因此它的构造函数最终将其绑定fptr到一个临时对象!你开始看到问题了,但无论如何,让我们结束循环:

  2. 该对象被分配给this->b[i]。这实际上是一个副本。

  3. 原始的临时对象被销毁。

最终结果是b[i]的绑定函数最终被绑定到一个临时对象,该对象现在已被销毁。这会导致未定义的行为和您的崩溃。

并与您的工作选择:

this->loc_ptr->set_of_cb.push_back(std::bind(&other::func, &(this->b[i])))

您正在将 绑定std::function到对象的有效实例,在b[i].

而已。


推荐阅读