user265906
user265906

Reputation: 170

How does a virtual table handle pure virtual functions

How does the compiler implement a pure virtual function? How is the vtable of a class having pure virtual functions implemented? Why do we always need to override pure virtual functions? What happens to the vtable of a derived class when we override a pure virtual function?

Upvotes: -1

Views: 362

Answers (1)

Alan Birtles
Alan Birtles

Reputation: 36488

The c++ standard doesn't specify the implementation of virtual methods.

Generally it's implemented as something like an array of function pointers, pure virtual functions are often pointers to some special function which throws an error.

You have to override pure virtual functions as otherwise when something tries to call those functions what would happen? If you don't want to have to override a particular function don't make it pure virtual in the base class.

For example you could emulate virtual functions with code like this:

#include <iostream>
#include <string>
#include <vector>

class A
{
public:
    A() : vtable(2)
    {
        vtable[0] = &A::aimpl;
        // B is pure virtual
        vtable[1] = &A::pureVirtualFunction;
    }

    void a()
    {
        ((*this).*(vtable[0]))();
    }

    void b()
    {
        ((*this).*(vtable[1]))();
    }

protected:
    std::vector<void (A::*)()> vtable;

private:
    void aimpl()
    {
        std::cout << "A::a\n";
    }

    void pureVirtualFunction()
    {
        throw std::runtime_error("function is pure virtual"); 
    }
};

class B : public A
{
public:
    B()
    {
        // Note: undefined behaviour!!! Don't do this in real code
        vtable[1] = reinterpret_cast<void (A::*)()>(&B::bimpl);
    }

private:
    void bimpl()
    {
        std::cout << "B::b\n";
    }
};

int main()
{
    A a;
    a.a();
    try
    {
        a.b();
    }
    catch (std::exception& ex)
    {
        std::cout << ex.what() << "\n";
    }
    B b;
    b.a();
    b.b();
    return 0;
}

The real implementation is more complex with derived classes being able to add to the vtable, merging vtables from multiple inheritance etc.

Upvotes: 3

Related Questions