深度探索C++对象模型之一 --- 关于对象
来源:互联网 发布:企业如何进行网络推广 编辑:程序博客网 时间:2024/06/11 16:27
深度探索C++对象模型之一 — 关于对象
使用封装之后的成本
从软件工程的眼光来看,“一个ADT或class hierarchy的数据封装”比“在C程序中程序性地使用全局数据”好。
加上封装之后,并没有增加布局成本。data member直接内含在每一个class object之中,而member functions虽然在class中声明,但是却不出现在object之中。而non-inline member function只会诞生一个函数实例。至于inline-function则会在每一个使用的地方产生一个函数实体。所以封装并没有增加object的布局成本,在布局和存取时间上的额外负担主要是有virtual引起的,包括:
- virtual function机制 用以支持一个有效率的“执行期绑定”
- virtual base class 用以实现“多次出现在继承体系中的base class,有一个单一而被共享的实例”
c++对象模式
在c++中,有两种class data member:static和nonstatic,有三种class member function:static、nonstatic和virtual。
那么对于一个对象来说,如果上面的集中members的话,一个对象是如何在内存中布局的呢?历史上一共出现过三种对象模式,下面逐次介绍。
简单对象模型
一个对象包含多个slots,每一个slot都指向一个data member或member function,因为每个slot包含的是一个指针,不是存储真正的数据类型,那么所占的空间就是指针的大小(4Bytes),因此object的大小就很容易算出来。(引入slot的概念)表格驱动对象模型
这种模型把class的members抽象成两种表,一张表存储data member,另外一张存储member function。而每个obejct中有两个slot,一个slot指向data member table,另一个则指向memer function table。(引入member function table的概念)C++对象模型
在这种对象模型中,nonstati data members被置于每一个class object中拥有自己的value,而static data members、static member functions以及nonstatic member functions都被放置在class object之外。而virtual function则是按照如下步骤实现:(1)在编译期间,编译器被该class产生一个virtual table,里面专门存放指向virtual functions的指针 (2)为每一个class object添加一个vptr指针,专门指向virtual table。vptr的设置都是由构造函数、析构函数、拷贝构造函数等自动完成。每一个class用来支持runtime type idetification的type_info object一般都会被存放在virtual table的第一个slot中。如下图所示:如果class是出在一个继承链当中那么一个class object又该如何布局呢?c++对象模型会将base class subobject的data members直接放置于derived class object中,而对于虚拟继承的virtual base class,因为无论在继承链中继承多少次,最后都只会有一个实体。Virtual base class的原始模型是在class object中为每一个有关联的virtual base class加上一个指针,直接指向virtual base class
单继承
- 子类没有重写的父类虚函数,就直接使用父类虚函数
- 子类覆盖父类的虚函数
- 子类新增的虚函数
多重继承
- 新增的虚函数放在第一个父类虚函数中
- 重写的虚函数要对所有类的虚函数都覆盖
- 内存布局中父类按照声明的顺序排列
简单虚拟继承
简单虚拟继承中derived class 新增的虚函数放在自己的vtbl中,增加一个vbptr指向virtual base class
菱形虚拟继承
菱形虚拟继承中derived class新增的虚函数仍然是放在第一个父类的vtbl中,每一个父类都有一个vbptr指向virtual base class,父类中不存放virtual base class的data members。
struct和class的关系
c++不区分都可以用,只是class封装的哲学理念。另外struct对于数据结构的尾端可以存放可变大小的数组,而class因为布局以及virtual机制的影响,不一定能够支持这种。如果要传递“一个复杂的class object的全部或部分”到某个C函数时,struct声明可以将数据封装起来,并保证拥有与C兼容的空间布局。
只有通过pointer或reference的间接处理才支持多态。c++以下列方法支持多态:
- 经由一组隐式的转化操作。如把一个derived class指针转化成一个指向其public base class指针
Shape *ps = new Circle();
- 经由virtual function机制:
ps->rotate();
- 经由dynamic_cast和typeid运算符:
if(circle *pc = dynamic_cast<circle *>(ps)) ...
class object大小
- nonstatic data member的总和大小
- 边界对其补充的大小
- 为了支持virtual而产生的内部负担
指针的类型
“指向不同类型的指针”的差异,既不在指针表示法不同,也不在其内容不同,而时在其所寻址出来的object类型不同。“指针类型”教导编译器如何解释某个特定地址中的内存内容及其大小。
转换(cast)其实是一种编译器指令,大部分情况下并不改变一个指针所含的真正的地址,而只影响“被指出内存的大小和其内容”的解释方式。
static_cast<> 和dynamic_cast<>
static_cast<?>()
可以用于在相关指针之间转换,void*指针间转换,还可以在基类和派生类之间转化,因为是在编译期间确定下来的,所以设计者必须自己确保安全性。
dynamic_cast<?>()
专门用于具有继承关系的类之间转换
- 深度探索C++对象模型之一 --- 关于对象
- 深度探索C++对象模型--关于对象
- 深度探索C++对象模型
- 深度探索C++对象模型第一章 关于对象
- 《深度探索c++对象模型》 学习笔记 - 1 关于对象
- 深度探索C++对象模型 关于对象的笔记
- 《深度探索C++对象模型》- 第1章 关于对象
- 《深度探索C++对象模型》读书笔记之关于对象
- 《深度探索C++对象模型》--1 关于对象
- 【深度探索C++对象模型】第一章 关于对象
- 深度探索c++对象模型(一)_关于对象
- 《深度探索C++对象模型》—关于对象(Object Lessons)
- 《深度探索C++对象模型》读书笔记第一章:关于对象
- 《深度探索C++对象模型》第一章 关于对象
- 《深度探索C++对象模型》第一章关于对象 摘录
- 《深度探索C++对象模型》
- 深度探索C++对象模型
- 深度探索C++对象模型
- Problem B: STL——多重集的插入和删除
- LeetCode:492. Construct the Rectangle
- 首次安装Robot Framework中遇到的坑
- Problem C: 分数类的输出
- Codeforces Round #223 (Div. 2)-C. Sereja and Prefixes
- 深度探索C++对象模型之一 --- 关于对象
- 三层架构
- django学习5 pymysql 数据库配置
- eclipse-Mars2-4.5.2安装Tomcat插件
- Problem D: 分数类的类型转换
- ubuntu火狐浏览器打不开百度www,baidu.com解决方法
- Angular2.0仿今日头条
- 人工智能全景图
- switch详解