I wrote some code and got scared that it will not work - so I wrote a prototype:
#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;
}
that compiles and works. (outputs 20
). But Why? Also I tested under VS2010 and wonder if it would work across platforms (say compiled under GCC)?
Mainly action = boost::bind(&base::onDataBaseReady, this, _1);
scares me - we say &base::
...
A pointer to a virtual
method does a virtual
function lookup when called.
#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)();
}
so, it "just works". The member function pointer (this->*&base::foo)()
is not the same as a fully qualified function call this->base::foo()
. The first is a way to store the foo
part of calling this->foo()
, the second is a way to skip virtual
method lookup and directly call base::foo
.