This is my code snippet:
class Base {
public:
Base() {
foo();
bind();
}
virtual void foo() {
std::cout << "base foo\n";
}
void bind() {
fn = std::bind(&Base::foo, this);
};
std::function<void()> fn;
};
class Derived : public Base {
public:
void foo() override {
std::cout << "derived foo\n";
}
void bind() {
}
int val;
};
int main() {
Base* p = new Derived();
p->fn();
}
The output is:
base foo
derived foo
foo()
prints base foo
, because at this point, the vtable still points to Base::foo
, according to answers under this question.
During the construction of Base
, the object is not yet of Derived
class. So, when calling std::bind()
the this
pointer is still a pointer to the Base
class, and the argument pointer is passed in the constructor body of Base
, so why does p->fn
call foo
in the Derived
class?
My compiler is Apple clang version 14.0.3
when called std::bind is still a pointer to Base class, and the argument pointer is passed in constructor body of Base, why p->fn called foo in derived class?
Once your Derived
constructor is called, every pointer to the Base
is now a pointer to Derived
. The vtable accessed from that location is now a Derived vtable
That's the "dynamic" part of dynamic dispatch.