第一章    关于对象

在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有所改动(可能是添加、移除或改动),那么那些应用程序代码相同得又一次编译。

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

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

  1. 18第一章 ASP.Net内建对象

    第一章        ASP.Net内建对象 第一章        ASP.Net内建对象 ASP.Net为保持用户的数据和信息,内建了许多对象,包括Application.Response.Requ ...

  2. 20190813 On Java8 第一章 对象的概念

    第一章 对象的概念 抽象 Alan Kay 总结了对象的五大基本特征 万物皆对象. 程序是一组对象,通过消息传递来告知彼此该做什么. 每个对象都有自己的存储空间,可容纳其他对象. 每个对象都有一种类型 ...

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

    第二章  创建和销毁对象 第一条 使用静态工厂方法替代构造器,原因: 静态工厂方法可以有不同的名字,也就是说,构造器只能通过参数的不同来区分不同的目的,静态工厂在名字上就能表达不同的目的 静态工厂方法 ...

  4. [Java编程思想] 第一章 对象导论

    第一章 对象导论 "我们之所以将自然界分解,组织成各种概念,并按其含义分类,主要是因为我们是整个口语交流社会共同遵守的协定的参与者,这个协定以语言的形式固定下来--除非赞成这个协定中规定的有 ...

  5. 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介

    前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...

  6. 第一章 数据库概述、MySQL的安装和配置

      第一章 数据库概述.MySQL的安装和配置   1.为什么要使用数据库 最早是纸质文件来存储数据 缺点:不易保存,占用空间大 计算机出现以后,采用软件来进行保存(excel) 缺点:容易损坏 文件 ...

  7. c#高级编程第七版 学习笔记 第一章 .NET体系结构

    第一章      .NET体系结构 本章内容: 编译和运行面向.NET的代码 Microsoft中间语言(Microsoft Intermediate Language,MSIL或简称IL)的优点 值 ...

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

    本系列的博客是由本人在阅读<JavaScript DOM编程艺术>一书过程中做的总结.前面的偏理论部分都是书中原话,觉得有必要记录下来,方便自己翻阅,也希望能为读到本博客的人提供一些帮助, ...

  9. javascript高级程序设计第一章有感

    第一章JavaScript简介 Javascript的诞生最早是为了处理表单数据验证的问题,以前主要是使用perl这个强大的服务端脚本语言处理的.在未诞生javascript之前, 人们每次提交表单就 ...

随机推荐

  1. [转]自适应网页设计(Responsive Web Design)

    本文转自:http://www.ruanyifeng.com/blog/2012/05/responsive_web_design.html 作者: 阮一峰 日期: 2012年5月 1日 随着3G的普 ...

  2. C#模拟百度登录并到指定网站评论回帖(一)

    核心信息: 请求网址:  https://passport.baidu.com/v2/api/?login请求方法:  POST状态码:  HTTP/1.1 200 OK请求头  //用户代理 Use ...

  3. Oracle12C用户创建、授权、登录

    Oracle12C用户创建.授权.登录 1.以系统用户登录 C:\Users\LEI>sqlplus sys/dwh as sysdba; SQL*Plus: Release 12.1.0.2. ...

  4. Android基础TOP4_1:点击物理按钮弹出退出提示框

    JAVA: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedIns ...

  5. Windows 10 IIS所有的html返回空白

    这是一个神奇的现象.因为使用IIS已经有N多年了,喜欢使用它是因为它随手可得.自从装上windows10以来,直至今天才用它来调试客户端程序.想在上面放一个静态的json数据,省的还要去建立一个Web ...

  6. html——表单控件

    基本的表单控件还有html5的一些新的表单控件: <!DOCTYPE html> <html> <head> <meta charset="utf- ...

  7. SQL基本操作——JOIN多表联查

    基本概念 join :用于根据两个或多个表中的列之间的关系,从这些表中查询数据. join和key:有时为了得到完整的结果,我们需要从两个或更多的表中获取结果.我们就需要执行 join.数据库中的表可 ...

  8. C# WinForm窗体应用(第四天)

    一.点击登录按钮,将两个窗体进行连接,并进行用户名和密码验证. /// <summary> /// 登录设置 /// </summary> /// <param name ...

  9. 微信 之jsapi实现支付

    一.微信公众号号后台支付配置 附微信支付参考文档:https://pay.weixin.qq.com/wiki/doc/api/index.html 二.微信支付类封装 该类可以实现付款码支付.JSA ...

  10. PHP 之base16加密解密封装

    /** * @Description: base16加密 * @Author: Yang * @param $data * @return string */ function base16_enco ...