Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a pointer to a (pure) virtual function from a base class instance

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.

like image 752
galinette Avatar asked Sep 01 '26 16:09

galinette


1 Answers

How can &Abstract::virtualFoo return 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.

like image 118
eerorika Avatar answered Sep 03 '26 08:09

eerorika



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!