虚拟表如何处理纯虚函数

问题描述 投票:0回答:1

编译器如何实现纯虚函数?具有纯虚函数的类的vtable如何实现?为什么我们总是需要重写纯虚函数?当我们重写纯虚函数时,派生类的vtable会发生什么?

c++ inheritance abstract-class virtual
1个回答
2
投票

c ++标准未指定虚拟方法的实现。

通常,它实现为类似于函数指针数组的方式,纯虚函数可能只是该数组中的空指针。

您必须重写纯虚函数,否则当某些东西试图调用这些虚函数时会发生什么?如果您不想重写特定的函数,请不要在基类中使其纯虚拟。

例如,您可以使用如下代码模拟虚拟函数:

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

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

    void a()
    {
        if (vtable[0])
        {
            ((*this).*(vtable[0]))();
        }
        else
        {
            throw std::runtime_error("A::a is pure virtual");
        }
    }

    void b()
    {
        if (vtable[1])
        {
            ((*this).*(vtable[1]))();
        }
        else
        {
            throw std::runtime_error("A::b is pure virtual");
        }
    }

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

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

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;
}

[真正的实现更加复杂,派生类能够添加到vtable中,可以合并来自多个继承的vtable等。

© www.soinside.com 2019 - 2024. All rights reserved.