在基本构造函数中绑定虚拟 class 成员函数
Bind virtual class member function in base constructor
下面的示例显示了一个基 class,它将虚拟成员函数绑定到 fn。在 gcc 4.8 上,在派生的 class 上调用 fn 将调用重载的计算函数。谁能解释为什么会这样?此行为与编译器无关吗?
#include <functional>
#include <iostream>
class Base {
public:
Base(){
fn = std::bind(&Base::calculate,this,1);
}
virtual int calculate(int value){
return value + 1;
}
std::function<int(int)> fn;
};
class Derived : public Base {
public:
Derived() : Base() {}
int calculate(int value){
return 0;
}
};
int main(int argc, const char **argv){
Derived test;
std::cout << test.fn(10) << std::endl;
/* Output of test.fn(10) is zero, so overloaded function was called */
return 0;
}
代码的行为符合预期:调用虚拟成员函数会分派到包含调用实例对象的最派生对象中最重写的函数。您使用成员函数指针(在绑定表达式内)这一事实没有任何区别;事实上,指向成员函数的指针的全部意义在于它们可以与虚拟分派一起正常工作。
如果你想对基函数进行非虚拟调用,你可以这样做:
Base() : fn([this]() { return this->Base::calculate(1); }) {}
下面的示例显示了一个基 class,它将虚拟成员函数绑定到 fn。在 gcc 4.8 上,在派生的 class 上调用 fn 将调用重载的计算函数。谁能解释为什么会这样?此行为与编译器无关吗?
#include <functional>
#include <iostream>
class Base {
public:
Base(){
fn = std::bind(&Base::calculate,this,1);
}
virtual int calculate(int value){
return value + 1;
}
std::function<int(int)> fn;
};
class Derived : public Base {
public:
Derived() : Base() {}
int calculate(int value){
return 0;
}
};
int main(int argc, const char **argv){
Derived test;
std::cout << test.fn(10) << std::endl;
/* Output of test.fn(10) is zero, so overloaded function was called */
return 0;
}
代码的行为符合预期:调用虚拟成员函数会分派到包含调用实例对象的最派生对象中最重写的函数。您使用成员函数指针(在绑定表达式内)这一事实没有任何区别;事实上,指向成员函数的指针的全部意义在于它们可以与虚拟分派一起正常工作。
如果你想对基函数进行非虚拟调用,你可以这样做:
Base() : fn([this]() { return this->Base::calculate(1); }) {}