C++对象模型
2016-05-10 18:02
399 查看
什么是C++对象模型?引用《深度探索C++对象模型》中的两个概念:
语言中直接支持面向对象程序设计的部分
对各种支持的底层实现机制
In my opinion 对象模型是对象在存储空间上的空间比时间更优,并对C++面向对象的技术加以支持,如虚指针虚表指针支持多态性。什么是多态?
●多态
C++中虚函数的作用主要是为了实现多态机制。多态,是指在继承层次中,父类的指针可以具有多种形态——当他指向某个子类对象时,通过它能调用到子类的函数,而非父类的函数。简单滴讲,当使用基类的指针或引用重写的虚函数时,当使用父类调用的就是父类的虚函数,指向子类就是子类的虚函数。
含有虚函数或其父类含有虚函数的类,编译器都会为其添加一个虚函数表vptr,(先了解虚函数表,有助于C++对象模型的理解)
继承下的C++对象模型。分析C++对象在下面情形中的内存布局:
单继承:子类单一继承自父类,分析了子类重写父类函数,子类定义了新的虚函数情况下子类对象的内存布局。
多继承:子类继承于多个父类,分析了子类重写父类函数,子类定义了新的虚函数情况下子类对象的内存布局,同时分析了虚继承下的菱形继承。
虚继承:分析了单一继承体系下的虚继承、多重基层下的虚继承、重复继承下的虚继承。
●虚表
当一个类本身定义了虚函数,或其父类有虚函数时,为了支持多态机制,编译器将为该类添加一个虚函数表指针,虚函数指针一般都放在对象内存布局的第一个位置上,这是因为保证在多层继承或多重继承下能最高效率地取到虚函数表。
当vptr位于对象内存最前面时,对象的地址即为虚函数指针地址。
每个类对象都拥有一个虚表指针, 由编译器为其生成。虚表指针的设定与重置皆由类的复制控制(也是构造函数,析构函数,赋值操作符)来完成。vptr的位置为编译器决定,传统上它被放在所有显示声明的成员之后, 不过现在许多编译器把vptr放在一个类对象的最前端。
●菱形继承
菱形继承也称钻石继承或重复继承,它指的是基类被某个派生类简单重复继承了多次,
●虚拟继承
菱形虚拟继承下,派生类对象又有不同的构成了,在D类的内存构成上,有以下几点:
在D类对象的内存中,基类出现的顺序是:先是B1类(最左父类),然后B2类(次左父类),最后是B类(虚祖父类)
菱形继承下的对象模型是:
语言中直接支持面向对象程序设计的部分
对各种支持的底层实现机制
In my opinion 对象模型是对象在存储空间上的空间比时间更优,并对C++面向对象的技术加以支持,如虚指针虚表指针支持多态性。什么是多态?
●多态
C++中虚函数的作用主要是为了实现多态机制。多态,是指在继承层次中,父类的指针可以具有多种形态——当他指向某个子类对象时,通过它能调用到子类的函数,而非父类的函数。简单滴讲,当使用基类的指针或引用重写的虚函数时,当使用父类调用的就是父类的虚函数,指向子类就是子类的虚函数。
#include<iostream> using namespace std; class Person { public: virtual void BuyTicket() { cout<<"买票"<<endl; } }; class Student { public: virtual void BuyTicket() { cout<<"买票半价"<<endl; } }; void Fun(Person& P) { P.BuyTicket(); } void Test() { Person P; Student S; Fun(P); Fun(S); }虚函数表解析
含有虚函数或其父类含有虚函数的类,编译器都会为其添加一个虚函数表vptr,(先了解虚函数表,有助于C++对象模型的理解)
继承下的C++对象模型。分析C++对象在下面情形中的内存布局:
单继承:子类单一继承自父类,分析了子类重写父类函数,子类定义了新的虚函数情况下子类对象的内存布局。
多继承:子类继承于多个父类,分析了子类重写父类函数,子类定义了新的虚函数情况下子类对象的内存布局,同时分析了虚继承下的菱形继承。
虚继承:分析了单一继承体系下的虚继承、多重基层下的虚继承、重复继承下的虚继承。
●虚表
class Base { public: Base(int i) :basel(i) {} vitual void print(void) { cout<<"调用了虚函数的Base::Print()"; } virtual stel() { cout<<"调用了虚函数的Base::stel()"; } virtual ~Base() {} private: int basel };
当一个类本身定义了虚函数,或其父类有虚函数时,为了支持多态机制,编译器将为该类添加一个虚函数表指针,虚函数指针一般都放在对象内存布局的第一个位置上,这是因为保证在多层继承或多重继承下能最高效率地取到虚函数表。
当vptr位于对象内存最前面时,对象的地址即为虚函数指针地址。
每个类对象都拥有一个虚表指针, 由编译器为其生成。虚表指针的设定与重置皆由类的复制控制(也是构造函数,析构函数,赋值操作符)来完成。vptr的位置为编译器决定,传统上它被放在所有显示声明的成员之后, 不过现在许多编译器把vptr放在一个类对象的最前端。
●菱形继承
菱形继承也称钻石继承或重复继承,它指的是基类被某个派生类简单重复继承了多次,
●虚拟继承
菱形虚拟继承下,派生类对象又有不同的构成了,在D类的内存构成上,有以下几点:
在D类对象的内存中,基类出现的顺序是:先是B1类(最左父类),然后B2类(次左父类),最后是B类(虚祖父类)
菱形继承下的对象模型是:
相关文章推荐
- c#中虚函数的相关使用方法
- C#类的多态性详解
- C++虚函数及虚函数表简析
- C++之普通成员函数、虚函数以及纯虚函数的区别与用法要点
- 构造函数不能声明为虚函数的原因及分析
- C++虚函数表实例分析
- C++虚函数的实现机制分析
- C++中虚函数与纯虚函数的用法
- 深入探讨C++父类子类中虚函数的应用
- 理解和运用PHP中的多态性[译]
- 解析C++编程中virtual声明的虚函数以及单个继承
- 详解C++编程中的虚函数
- PHP5多态性与动态绑定介绍
- 深入解析C++中的虚函数与多态
- C#常用知识点简单回顾(有图有真相)
- 浅析C++中的虚函数
- c++中虚函数和纯虚函数的作用与区别
- 虚函数与纯虚函数(C++与Java虚函数的区别)的深入分析
- 浅谈C++基类的析构函数为虚函数
- 简单解读C++中的虚函数