C++笔记——多态原理探究
2015-12-30 11:28
260 查看
C++中的多态表现在同一语句表现出不同的形态。
我们知道,C++编译器是通过virtual关键字实现的多态,即C++编译器会默认为我们添加一个VPTR指针在对象里面,并且维护一个VTABLE的结构,VPTR指针就指向这么一个结构,这个结构里面存放这所有virtual关键字的函数。当执行某个语句时就是通过对象的VPTR指针来找到对应的virtual方法,来实现多态的。
在这里,我想验证一下,所谓的VPTR指针是实实在在存在的。代码如下:
分析结果我们发现,相同的类成员,加了virtual关键字的比没加关键字的多了12个字节的数据,因为我的机器是64位,默认8字节对齐的,所以其实Child类比Parent类多8个字节的数据,如第一条打印,指针大小正是8个字节。所以,我们可以得出结论。C++编译器为我们默认加了VPTR指针,来实现多态。
正如之前博文所说,不加virtual关键字,是静态联编,即C++编译器在编译阶段就绑定了调用原则。而加了virtual关键字是动态联编,即在运行期间根据对象类型,找到对象的VPTR指针,再找到VTABLE结构,去找到所要调用的方法,这样就实现了C++中强大的多态机制。
我们知道,C++编译器是通过virtual关键字实现的多态,即C++编译器会默认为我们添加一个VPTR指针在对象里面,并且维护一个VTABLE的结构,VPTR指针就指向这么一个结构,这个结构里面存放这所有virtual关键字的函数。当执行某个语句时就是通过对象的VPTR指针来找到对应的virtual方法,来实现多态的。
在这里,我想验证一下,所谓的VPTR指针是实实在在存在的。代码如下:
#include <iostream> using namespace std; class Parent { public: Parent(int a = 0) { this->a = a; cout<<"Parent()"<<endl; } void print() { cout<<"Parent a="<<a<<endl; } private: int a; }; class Child { public: Child(int b = 0) { this->b = b; cout<<"Child()"<<endl; } virtual void print() { cout<<"Child b = "<<b<<endl; } private: int b; }; int main(void) { cout<<"*p ="<<sizeof(char *)<<endl; cout<<"Parent size="<<sizeof(Parent)<<endl; cout<<"Child size="<<sizeof(Child)<<endl; return 0; }编译运行,结果如下:
分析结果我们发现,相同的类成员,加了virtual关键字的比没加关键字的多了12个字节的数据,因为我的机器是64位,默认8字节对齐的,所以其实Child类比Parent类多8个字节的数据,如第一条打印,指针大小正是8个字节。所以,我们可以得出结论。C++编译器为我们默认加了VPTR指针,来实现多态。
正如之前博文所说,不加virtual关键字,是静态联编,即C++编译器在编译阶段就绑定了调用原则。而加了virtual关键字是动态联编,即在运行期间根据对象类型,找到对象的VPTR指针,再找到VTABLE结构,去找到所要调用的方法,这样就实现了C++中强大的多态机制。
相关文章推荐
- 【C++】类的使用
- C#调用C++ Dll 并且实现联调
- C语言缓冲区(缓存)详解
- C++开发人脸性别识别教程(1)——前瞻
- 指针和引用的区别
- const全局变量和局部变量
- C语言输出 编译器为变量分配的内存地址 %p
- c++动态内存开辟之 new 的三种形态
- 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
- C语言的函数类型
- C++中异常处理
- C++多态之继承7-多重继承
- C语言宏定义使用技巧
- C语言宏定义和宏定义函数
- Flume thrift source C++ Demo
- Keil STM32 C++混合编程要点
- C++强制类型转换
- C++ namespace + std::bind std::function
- 5、vc++设置Excel颜色
- GDB 调试