I have the following c++11 code, which works, while I would have expected it to crash or even not to compile. Retrieving a pointer to a pure virtual member function should return a null or invalid pointer, or should be blocked by the compiler. I would like to understand why it works.
I know there are other (better) ways to code this, this is a purely theoritical question for understanding what the syntax does.
#include <iostream>
#include <functional>
class Abstract
{
public:
void foo()
{
auto func = std::bind(&Abstract::virtualFoo, this);
func();
}
protected:
virtual void virtualFoo() = 0;
};
class Derived1 : public Abstract
{
private:
void virtualFoo() override
{
std::cout << "I am Derived1\n";
}
};
class Derived2 : public Abstract
{
private:
void virtualFoo() override
{
std::cout << "I am Derived2\n";
}
};
int main(int argc, char *argv[])
{
Abstract * a1 = new Derived1;
Abstract * a2 = new Derived2;
a1->foo();
a2->foo();
return 0;
}
The intent is quite clear, in the base class function foo() I want to get a pointer on the derived virtual functions.
However, to my understanding, it should not work, and should not even compile with a pure virtual function. With a non pure virtual function, it should execute the base class function. But, I was very surprised to see it compiles, and produces the intended output : it prints "I am Derived1" then "I am Derived2"
How can &Abstract::virtualFoo return a valid pointer, without even knowing the pointer to the actual object, mandatory for accessing a vtable???
Online C++ link : https://onlinegdb.com/SJfku8rvV
To me, a valid syntax should be:
auto func = std::bind(&this->virtualFoo, this);
As dereferencing this should actually access the vtable and return a function pointer. But the c++11 doesn't think this way.
How can
&Abstract::virtualFooreturn a valid pointer, without even knowing the pointer to the actual object, mandatory for accessing a vtable???
You've declared the function to be virtual. The compiler knows that the function is virtual. The standard requires that calling through the member function pointer does a virtual dispatch.
The compiler stores the necessary information into the member function pointer to make that happen. Note that a member function pointer is not necessarily merely a pointer to a single address. It can contain more than that.
The exact way in which the compiler achieves this is implementation defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With