有关VTables的在线资源很多.他们通常对此有相同的陈述:
" 只要类本身包含虚函数或覆盖父类的虚函数,编译器就会为该类构建一个vtable.这意味着并非所有类都有编译器为它们创建的vtable .vtable包含指向的类的函数指针.该类中的虚函数.每个类只能有一个vtable,同一个类的所有对象将共享相同的vtable. "
那么为什么这意味着并非所有类都有编译器为它们创建的vtable?是因为somc类没有虚函数吗?
正是.有些类没有vtable,因为它们没有任何虚拟方法.
虚方法是编译器无法生成直接调用的方法,因为它根据类的实现而变化.Vtables是一种查找表,通过延迟在程序运行期间调用哪个实现的决定来解决这个问题:编译器在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();
Run Code Online (Sandbox Code Playgroud)
这将打印出来Bar的消息.在大多数非平凡的场景中,编译器无法事先知道调用虚方法的对象的类型.如上所述,vtable通过提供统一的查找机制来找到方法实现来解决问题,无论对象的类型如何.
vtable指针必须存在于类的每个实例中(这需要额外内存指针的大小,可能是4或8个字节),以及程序地址空间中某些不重要的静态内存.这对你来说似乎并不是很多(事实上很多人会同意),但在某些情况下(例如内存非常有限的嵌入式系统),这可能很麻烦.拥有每个类的vtable会违反您只为所使用的内容付费的一般C++原则,因此如果不需要,编译器不会生成任何vtable.
不具有虚表具有禁用的显着副作用ř未吨 IME 吨 YPE 我载文信息.如果需要在代码中使用RTTI,则类必须至少具有一个虚方法.惯例是在这些情况下将析构函数标记为虚拟.
小智 5
实际上,C++中没有任何内容要求任何类都有vtable - 这完全是一个实现问题.但是,具有虚函数的类必须以某种方式支持多态函数调用,并且这将始终需要某种类型的表/映射.此表/映射将由编译器为具有多态函数的类创建,并且可能(根据编译器质量)为不具有多态函数的类创建.
| 归档时间: |
|
| 查看次数: |
2869 次 |
| 最近记录: |