c++ - 如果一个类具有公有、私有和受保护的虚函数,会有多少个虚表?
问题描述
我在 C++ 中读到,如果该类至少有一个虚函数,编译器会为该类设置一个虚拟表。编译器还为每个指向该类的虚拟表的对象实例添加一个隐藏指针。
考虑以下类:
class A
{
public:
virtual int functionA(void) { return 0; }
private:
virtual int functionB(void) { return 1; }
protected:
virtual int functionC(void) { return 2; }
};
对于每个访问说明符,此类的对象是否有一个指向虚拟表的指针或三个不同的指向虚拟表的指针?
解决方案
首先,理解 C++ 标准中没有提到“虚拟表”是非常重要的。C++ 标准规定了 C++ 程序的结果和预期行为。
“虚拟表”只是导致 C++ 程序的预期行为的实现细节。只要结果符合 C++ 标准的规定,C++ 实现就可以以某种不使用“虚拟表”服务的方式自由地实现虚拟类方法。说了这么多:
现代 C++ 编译器中虚拟继承的典型实现总是使用单个虚拟表。单个类方法(虚拟与否)是私有的、受保护的还是公共的:这就是访问控制。在编译时检查访问控制。前提是 C++ 程序不会以使生成的代码格式错误并导致编译错误的方式访问私有/受保护的类成员:您的最终结果是具有虚函数的类和对象;并且在运行时所有虚函数都是相似的,只需要一个虚拟表来调度它们。
作为 PS:使用现代 C++ 编译器中的链接时优化技术,我不会惊讶地发现我的 C++ 编译器发现在我的 C++ 程序中,虚拟类方法实际上永远不会被覆盖,如果所有类都是如此成员因此没有创建虚拟表。
推荐阅读
- javascript - history back() 方法关闭新打开的标签
- angular - 使用拦截器刷新令牌
- python - 我如何用numpy计算n个向量的n个张量的点积
- arrays - Swift Array 随机插入和删除非常慢
- model - Pocketsphinx 构建小词汇模型
- html - 在文本旁边添加按钮时如何保持文本对齐
- php - 使用 Vue 组件和 Blade 时,在 Laravel 中更新语言环境的最佳方法是什么?
- java - 无法构建管道无元素解码器[Gstreamer]
- javascript - 如何使用 get/fetch 语句传递参数(express)
- html - 如何根据表格的其他列值使按钮不可见 - Angular