c++ - 回调函数向量和函数指针绑定
问题描述
我是新手,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;
}
解决方案
other(SomeClass *loc, int id){
this->id = id;
this->loc =loc;
fptr = std::bind(&other::func,this);
}
构造函数绑定fptr
到this
,这是构造的对象。现在,请注意:
this->b[i] = other(this, i);
这将执行以下事件序列。这里发生了很多事情,这对这个谜团至关重要:
一个临时
other
对象被构造出来,它的构造函数做它所做的事情。请注意,该对象是临时的,因此它的构造函数最终将其绑定fptr
到一个临时对象!你开始看到问题了,但无论如何,让我们结束循环:该对象被分配给
this->b[i]
。这实际上是一个副本。原始的临时对象被销毁。
最终结果是b[i]
的绑定函数最终被绑定到一个临时对象,该对象现在已被销毁。这会导致未定义的行为和您的崩溃。
并与您的工作选择:
this->loc_ptr->set_of_cb.push_back(std::bind(&other::func, &(this->b[i])))
您正在将 绑定std::function
到对象的有效实例,在b[i]
.
而已。