gpt4 book ai didi

c++ - 是否所有类都有编译器为它们创建的 Vtable?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:10:18 34 4
gpt4 key购买 nike

网上有很多关于虚表的资源。他们通常对他们有相同的陈述:

"只要类本身包含虚函数或重写父类的虚函数,编译器就会为该类构建一个 vtable。这意味着并非所有类都有编译器为它们创建的 vtable。 vtable 包含指向该类中虚函数的函数指针。每个类只能有一个 vtable,同一类的所有对象将共享同一个 vtable。"

那么,为什么这意味着并非所有类都有编译器为它们创建的虚表呢?是不是因为somc类没有虚函数?

最佳答案

没错。有些类没有虚表,因为它们没有任何虚方法。

虚方法是您的编译器无法为其生成直接调用的方法,因为它因类的实现而异。 Vtable 是一种查找表,它通过在程序运行时延迟决定调用哪个实现来解决此问题:您的编译器不是生成函数调用,而是在 vtable 上生成方法查找,然后调用返回的方法.

举个例子:

class Foo
{
public:
virtual void vMethod()
{
std::cout << "Foo::vMethod was called!" << std::endl;
}
};

class Bar : public Foo
{
public:
virtual void vMethod()
{
std::cout << "Bar::vMethod was called!" << std::endl;
std::cout << "This is not the same as Foo::vMethod." << std::endl;
}
};

Foo* foo = new Bar;
foo->vMethod();

这将打印 Bar 的消息。在大多数重要场景中,您的编译器无法提前知道调用虚方法的对象的类型。如上所述,无论对象的类型如何,vtable 通过提供统一的查找机制来查找方法实现来解决这个问题。

类的每个实例中都必须存在一个 vtable 指针(这需要额外内存指针的大小,可能是 4 或 8 个字节),以及程序地址空间中某处的一些微不足道的静态内存。这对您来说可能看起来并不多(实际上很多人会同意),但在某些情况下这可能很麻烦(例如内存极其有限的嵌入式系统)。为每个类创建 vtable 会违反一般的 C++ 原则,即您只需为使用的内容付费,因此如果不需要,编译器不会生成任何 vtable。

没有 vtable 会产生显着的副作用,即禁用 runttime type iinformation .如果您需要在代码中使用 RTTI,您的类必须至少有一个虚方法。在这些情况下,约定是将析构函数标记为虚拟。

关于c++ - 是否所有类都有编译器为它们创建的 Vtable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5709892/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com