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
Once your
Derivedconstructor is called, every pointer to theBaseis now a pointer toDerived. The vtable accessed from that location is now a Derived vtableThat's the "dynamic" part of dynamic dispatch.