C++ 绑定和虚拟函数重载:它们为什么工作?

C++ 绑定和虚拟函数重载:它们为什么工作?,c++,boost,boost-bind,boost-function,C++,Boost,Boost Bind,Boost Function,我写了一些代码,害怕它不能工作-所以我写了一个原型: #include <boost/function.hpp> #include <boost/bind.hpp> #include <iostream> class base { private: boost::function<void (int)> action; protected: virtual void onDataBaseReady(int i) { std::co

我写了一些代码,害怕它不能工作-所以我写了一个原型:

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

class base {
private:
    boost::function<void (int)> action;
protected:
    virtual void onDataBaseReady(int i) { std::cout << i << std::endl; }
public:
    void call() {
        action(10);
    }

    base() {
        action = boost::bind(&base::onDataBaseReady, this, _1);
    }
};

class child : public base {
protected:
    virtual void onDataBaseReady(int i) { std::cout << i+10 << std::endl; }
};

int main()
{
    static child c;
    c.call();
    std::cin.get();
    return 0;
}
#包括
#包括
#包括
阶级基础{
私人:
功能动作;
受保护的:

virtual void onDataBaseReady(inti){std::cout指向
virtual
方法的指针在调用时执行
virtual
函数查找

#include <iostream>
#include <memory>

struct base {
  virtual void foo() { std::cout << "base\n"; }
  virtual ~base() {}
};

struct derived:base {
  void foo() override final { std::cout << "derived\n"; }
};

int main() {
  void (base::*mem_ptr)() = &base::foo;
  std::unique_ptr<base> d( new derived() );
  base* b = d.get();
  (b->*mem_ptr)();
}
#包括
#包括
结构基{
虚拟void foo(){std::cout*&base::foo()()
与完全限定的函数调用
this->base::foo()
不同。第一种方法是存储调用
this->foo()
foo部分,第二种方法是跳过
virtual
方法查找并直接调用
base::foo

主要是action=boost::bind(&base::onDataBaseReady,这个,_1);让我害怕-我们说&base:

如果它执行静态调度,而不是动态调度,那么它将更加可怕。请考虑这个简单的例子:

struct base {
   virtual void foo() { /* maintain some invariants */ }
};
struct derived : base {
   virtual void foo() { /* maintain different invariants */ }
};

然后考虑将函数绑定到父对象上并调用派生对象。<代码>派生的执行器知道什么不变量适用于派生类型,它可能与基类型中的不变量相同,子集或完全不同。

void apply(base & b) {
   std::bind(&base::foo, &b)();
}
如果在绑定时解析了分派,并且函子应用于派生类型(您可能不知道其确切类型!)然后,派生类型的不变量可能会被破坏。在
apply
函数的上下文中,不可能知道对象到底是什么,或者该类型的不变量是什么,因此您可能想做的是让动态分派发挥其魔力


[这是从高级设计的角度来看的,甚至没有详细说明您不能使用指向成员的指针来执行静态分派…]

我们说&base::…我们指向一个具有多态行为的函数。如果它不调用最终重写器,我会感到害怕!@idmean抱歉,我对拥有原始指针有宗教上的反对意见。