【结论】
对于基类的实现函数,如果子类中要绑定到一个函数对象,同样需要将该实现函数声明为virtual的。
【现象】
父类中被绑定的函数,对类的成员变量操作,出现非预期的效果。
如:对一个int进行递增,递增到某个时刻,又从0开始重新递增。
class Parent
{
public:
Parent() : mem1(0) {}
~Parent() = default;
protected:
void func1()
{
for (int i = 0; i < 5000; i++)
{
mem1++;
fprintf(stderr, "mem1:%d\n", mem1);
}
}
private:
int mem1;
};
class Child : public Parent
{
public:
Child() = default;
~Child() = default;
public:
void setCallback()
{
// 此处bind内第一个参数使用&Parent::func1会出现编译错误, 因为Parent::func1是protected
setCallback(std::bind(&Child::func1, this)); // 伪代码
}
};
- 如果以上Child设置了回调函数,回调函数被某个调用执行了,在printf的结果中,会出现mem1从1到某个不固定数(110左右)的循环。
- 如果将Parent::func1设置为virtual的,就不会出现随机循环的现象。
这种现象如何用官方语言标识,有知道的请留言。
感兴趣的同学可以将上述的伪代码补全,看一下结果。