C++对象模型——关于对象(第一章)

第一章    关于对象

在C语言中,"数据"和"处理数据的操作(函数)"是分开声明的,也就是说,语言本身并没有支持"数据和函数"之间的关联性.我们把这样的程序方法成为程序性,由一组"分布在各个以功能为导向的函数中"的算法所驱动,它们处理的是共同的外部数据.举个样例,假设声明一个struct Point3d,像这样:

typedef struct point3d
{
    float x;
    float y;
    float z;
} Point3d;

欲打印一个Point3d,可能就得定义一个像这种函数:

void Point3d_print (const Point3d *pd) {
    printf("(%g, %g, %g)", pd->x, pd->y, pd->z);
}

或者,假设要想更有效率一些,就定义一个宏:

#define Point3d_print(pd)     printf("(%g, %g, %g)", pd->x, pd->y, pd->z);

也可直接在程序中完毕其操作

在C++中,Point3d有可能用独立的"抽象数据类型(abstract data type)来实现:

class Point3d
{
public:
    Point3d(float xval = 0.0, float yval = 0.0, float zval = 0.0)
        : x(xval), y(yval), z(zval) {}
    float getX() { return x; }
    float getY() { return y; }
    float getZ() { return z; }
    void setX(float xval) { x = xval; }
private:
    float x;
    float y;
    float z;
};
inline ostream & operator << (ostream &os, const Point3d &pt) {
    os << "(" << pt.getX() << ", " << pt.getY() << ", " << pt.getZ() << ")";
}

更进一步来说,无论哪一种形式,它们都能够被參数化,能够是坐标类型的參数化.

template <class type>
Point3d(type xval = 0.0, type yval = 0.0, zval = 0.0);

也能够是坐标类型和坐标数目两者都參数化:

template <class type, int dim>
Point(type coords[dim]);

非常明显,不仅仅是程序风格上有截然的不同,在程序的思考上也有明显的差异,从软件project的眼光来看"一个ADT或者class hierarchy的数据封装"比"在C程序中程序性使用全局数据"好.,可是这被那些"被要求高速让一个应用程序上马应战,而且运行起来又快又有效率"的程序猿所忽略,毕竟C的吸引力就在于它的精瘦和简易.

加上封装后的布局成本(Layout Costs for Adding Encapsulation)

程序猿看到Point3d转换成C++之后,第一个可能会问的问题就是:加上了封装之后,布局成本添加了多少?答案是class Point3d并没有添加成本,三个data member直接内含在每个class object之中,就像C struct的情况一样,而member functions尽管含在class的声明内,却不出如今object中,每个non-inline
member function仅仅会诞生一个函数实体,至于每个"拥有零个或者一个定义"的inline function则会在其每个使用者(模块)身上产生一个函数实体.Point3d支持封装性质,这一点并未带给它不论什么空间或运行期的不良效应.C++在布局以及存取时间上基本的额外负担是由virtual引起,包含:

virtual function机制    用于支持一个有效率的"运行器绑定"(runtime binding)

virtual base class        用以实现"多次出如今继承体系中的base class,有一个单一而被共享的实体"

此外,另一些多重继承下的额外负担,发生在"一个derived class和其第二或者后继之base class的转换"之间.然而,一般言之,并理由说C++程序一定比C庞大或者迟缓.

1.1    C++对象模式(The C++ Object Model)

在C++中,有两种class data members:static 和 nonstatic,以及三种class member functions:static,nonstatic和virtual,已知以下这个class Point声明:

class Point {
public:
    Point(float xval);
    virtual ~Point();

    float getX() const;
    static int PointCount();
protected:
    virtual ostream& print(ostream &os) const;
    float x;
    static int point_count;
};

这个class Point在机器中会被如何表现呢?也就是说,如何模拟(modeling)出各种data members和function members呢?

1.1.1    简单对象模型 (A Simple Object Model)

第一个模型很easy,它可能是为了尽量减少C++编译器的设计复杂度而开发出来的,缺点则是空间和运行期的效率低下.在这个简单模型中,一个object是一系列的slot(槽),每个slot指向一个member.Members依照声明次序,各自被指定一个slot.每个data member或function member都有自己的一个slot.

在这个简单模型中,members本身并不被放在object之中,仅仅有"指向member的指针"才被放在object内,这么做能够避免"members有不同的类型,因而须要不同的存储空间"所导致的问题.Object中的members是以slot的索引值来寻址,本例中x的索引值是6,point_count的索引值为7.一个class object的大小非常easy计算出来:"指针大小,乘以class中声明的members数目".

尽管这个模型并没有被应用于实际产品上,只是关于索引或slot数目的观念,倒是被应用到C++的"指向成员的指针"(point-to-member)观念之中.

1.1.2    表格驱动对象类型 (A Table-driven Object Model)

为了对全部classes的全部objects都有一致的表达方式,还有一种对象模型是把全部与members相关的信息抽出来,放在data member table和一个member function table之中,class object本身则内含这两个表格的指针,Member function table是一系列的slots,每个slot指出一个member function; Data member table则直接含有data本身.

尽管这个模型也没有实际应用于真正的C++编译器上,但member function table这个观念却称为支持virtual functions的一个有效方案.

1.1.3    C++对象模型 (The C++ Object Model)

Stroustrup当初设计(当前仍占有优势)的C++对象模型是从简单对象模型派生而来的,并对内存空间和存取时间做了优化.在此模型中,Nonstatic data members被配置于每个class object之内,static data members则被存放在全部的class object之外,Static和nonstatic function members也被放在全部的class object之外,Virtual functions则以两个步骤支持之:

1.每个class产生出一堆指向virtual functions的指针,放在表格之中,这个表格被称为virtual table(vtbl)

2.每个class object被加入了一个指针,指向相关的virtual table,通常这个指针被称为vptr.vptr的设定和重置都由每个class的constructor,destructor和copy assignment运算符自己主动完毕,每个class所关联的type_info object也经由virtual table被指出来,一般是放在表格的第一个slot处.

C++对象模型的主要长处在于它空间和存取时间的效率主要缺点是。假设应用程序代码本身并未改变,但所用的class object的nonstatic data members有所改动(可能是添加、移除或改动),那么那些应用程序代码相同得又一次编译。

关于这点,前面的的表格驱动模型就提供了较大的弹性,由于它多提供了一层间接性。只是它也因此付出空间和运行效率双方面的代价。

时间: 2024-11-07 00:49:24

C++对象模型——关于对象(第一章)的相关文章

【深度探索C++对象模型】第一章 关于对象

第一章 关于对象(Object Lessons) -- 本书作者:Stanley B.Lippman 一.前言 什么是 C++ 对象模型:简单的说,就是 C++ 中面向对象的底层实现机制. 本书组织: 第 1 章,关于对象(Object Lessons),介绍 C++ 对象的基础概念,给读者一个粗略的了解. 第 2 章,构造函数语意学(The Semantics of Constructors),构造函数什么时候会被编译器合成?它给我们的程序效率带来了怎样的影响? 第 3 章,Data语意学(T

[Effective Java 读书笔记] 第二章 创建和销毁对象 第一条

第二章  创建和销毁对象 第一条 使用静态工厂方法替代构造器,原因: 静态工厂方法可以有不同的名字,也就是说,构造器只能通过参数的不同来区分不同的目的,静态工厂在名字上就能表达不同的目的 静态工厂方法不用每次调用的时候都创建新的对象(其实是因为它是static的,所以只能用static的,所以是一早就创建了,不需要重复创建吧..),比如书中 Boolean.valueOf(boolean) 1 public static final Boolean TRUE = new Boolean(true

标准库》第一章 Object对象

(本文为阮一峰js标准教程的学习笔记,旨在总结该教程中涉及的知识点大纲及个人所做的一些拓展,方便作为"目录"或者"大纲"复习和查漏补缺,详细内容请参见阮一峰教程原文) 第三部分 标准库 ****************第一章 Object对象****************** 一.概述1.js原生提供Object对象2.首字母大写其他所有对象都继承自这个对象,它相当于其他编程语言中基类这一层概念的体现,而其他由此派生的类都是子类Object本身也是一个构造函数,可

JavaScript第一章

学习了javascript第一章,对js有了初步的了解. 首先,javascript主要由三个部分组成:核心(ECMAScript).文档对象模型(DOM).浏览器对象模型(BOM) ECMAScript主要是用来提供核心语言,它包括语法.类型.语句.关键字.保留字.操作符以及对象.需要web浏览器等宿主环境提供基本的ECMAScript实现,同时宿主环境也可提供语言等. DOM是针对XML经过扩展后用于HTML的应用程序编程接口,它可以把整个页面映射为一个多层节点结构.借助于DOM,人们可以实

JavaScript DOM编程艺术第一章:JavaScript简史

本系列的博客是由本人在阅读<JavaScript DOM编程艺术>一书过程中做的总结.前面的偏理论部分都是书中原话,觉得有必要记录下来,方便自己翻阅,也希望能为读到本博客的人提供一些帮助,所以 如果您也看过这本书,希望不要喷小的"抄袭",其实我也懒得敲这些文字也想简单粗暴地上代码,但是只有实践没有理论不容易自己理解,为避免误导,该"抄"的地方还是要"抄"的,哈哈~~ 一.JavaScript的起源 JavaScript是Netscap

《DirectX 9.0 3D游戏开发编程基础》 第一章 初始化Direct3D 读书笔记

REF设备 参考光栅设备,他能以软件计算方式完全支持Direct3D Api.借助Ref设备,可以在代码中使用那些不为当前硬件所支持的特性,并对这此特性进行测试. D3DDEVTYPE 在程序代码中,HAL设备用值D3DDEVTYPE_HAL来表示.该值是一个枚举变量.REF设备用D3DDEVTYPE_REF来表示.这种类型非常重要,你需要铭记,因为在创建设备的时候,我们必须指定使用哪种设备类型. COM(组件对象模型) 创建COM接口时不可以使用c++关键字new.此外使用完接口,应调用Rel

读书笔记 - javascript 高级程序设计 - 第一章 简介

第一章 简介   诞生时间 1995 最初用途 客服端验证 第一版标准 注意是标准 1997年 Ecma-262  一个完整的js实现由三部分组成 ECMAScript DOM 文档对象模型 BOM 浏览器对象模型 ECMAScript的宿主环境 web浏览器 Node(服务器js平台) adobe flash js和as的关系 他们都实现了 ECMAScript 五大主流浏览器 IE Firefox Safari Chrome Opera dom介绍 它是针对xml但经过扩展用于html的应用

javascript高级程序设计 第一章--javascript简介

javascript高级程序设计 第一章--javascript简介Netscape开发的javascript最初的目的就是处理由服务器负责的一些输入验证操作,而在js问世之前,必须                    把表单数据发到服务器端用户才能得到反馈.如今的js不再局限于简单的数据验证,而且具备了与浏览器窗口及其内容等所有方面的交互能力,js已经发展成功能全面的面向客户端的编程语言.javascript由Netscape公司开发,原名Livescript,是为了迎合当时的java热,所

JavaScript学习笔记(第一章——第三章)

说明 参考资料:<JavaScript高级程序设计(第3版)> 笔记主要为<JavaScript高级程序设计(第3版)>读书记录,按照此书的章节学习记录.方便以后查询复习(PS:正版书99大洋,没舍得买.在淘宝46买了一本盗版的并带一本 <JavaScript DOM编程艺术(第2版)>).两本书同时阅读,但以<JavaScript高级程序设计(第3版)>为主要学习路线.重要说明性内容将以近似书中原文摘出(以免出现个人解释歧义),外加自己遇到特殊情况说明(不