对《深入C++对象模型》中的一个疑问——虚函数表的type_info的位置

[ 转载请注明来自CoderJeff的优快云博客:http://blog.youkuaiyun.com/coderjeff/article/details/46544171,谢谢!]


在《深入C++对象模型》中,介绍vptr的指向时,第一个指向的是type_info,其次才是第一个虚函数的地址。但参考了下面这篇文章和其中的例子后,而且也经过自己的实验,发现不是那么回事,vptr指向的第一个位置其实是第一个虚函数的地址。

C++ 虚函数表解析 [面试很常考]


文章[C++对象模型][10]类型转化提到的另一篇文章:对象与对象的类型信息----获取对象的RTTI信息

有下面几句代码:

Aclass* ptra

### C++ 中继承与多态的使用示例及原理 #### 一、继承的基础概念 C++ 支持通过继承来构建类之间的层次关系。继承可以分为 `public`、`protected` 和 `private` 三种形式,每种形式决定了基类成员在派生类中的访问权限[^2]。 以下是不同继承方式下基类成员的可见性变化: - **Public 继承**: 基类的公有和保护成员保持不变,在派生类中仍可被访问。 - **Protected 继承**: 基类的公有和保护成员变为受保护成员,无法直接通过派生类的对象访问。 - **Private 继承**: 基类的公有和保护成员都成为私有成员,仅限于派生类内部访问。 #### 二、多态的概念及其应用 多态允许程序在运行时动态决定调用哪个方法版本,通常依赖于虚函数机制实现。为了支持多态行为,C++ 提供了虚拟表(vtable)作为底层支撑结构[^3]。 ##### 虚函数的作用 当声明某个函数为虚函数时,它表示该函数可以在派生类中重新定义并覆盖原始功能。如果希望强制要求子类提供自己的实现,则应将此函数标记为纯虚函数 (`=0`) 并将其所在类设置成抽象类。 ```cpp class Animal { public: virtual void Speak() const = 0; // 纯虚函数 }; class Dog : public Animal { public: void Speak() const override { std::cout << "Woof!" << std::endl; } }; ``` 上述例子展示了如何创建一个具有多态特性的动物模型体系。注意这里使用了现代标准推荐的关键字 `override` 来增强代码安全性以及清晰度[^1]。 #### 三、多态的工作原理解析 每当实例化含有至少一个虚函数的类对象时,编译器会为其分配一块额外存储空间用于保存指向相应类型的虚拟表格地址——即所谓的“虚函数指针”。这个过程完全透明给开发者,但在调试工具的帮助下可以看到实际布局情况: ```cpp #include <iostream> using namespace std; class Base { public: virtual ~Base(){} virtual void funcA(){ cout<<"Base A"<<endl;} virtual void funcB(){ cout<<"Base B"<<endl;} }; int main(){ Base obj; } // VS Debug Mode Output (Assume Address of Obj is 0x004DFAF8): /* Name Value Type obj {...} Base +vfptr 0x00E917FC int * */ ``` 从上面的例子可以看出即使没有任何显式的操作涉及到 vfptr ,但它确实存在并且初始化好了正确的值以便后续能够正确解析到各个具体的覆写版函数位置上。 #### 四、注意事项 尽管利用继承与多态能极大提高软件设计灵活性,但也需要注意一些潜在陷阱比如双重删除问题或者忘记释放资源等等。因此建议总是定义虚析构函数以确保安全销毁整个继承链上的所有部分。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值