第一章    关于对象

在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. mysql远程服务器访问数据库

    创建一个MySQL用户,并设置可以远程访问 grant usage on *.* to 'fred'@'localhost' identified by 'fred';//创建用户fred密码ferd ...

  2. 自学Python十二 战斗吧Scrapy!

    初窥Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 还是先推荐几个学习的教程:Scrapy 0.2 ...

  3. Linux学习(一)--基本概念

    一.Linux概述 Linux是一款全球性的免费的开源的操作系统平台,其特点是实现了多任务多用户处理,主要是依赖内核kernel shell,且占用资源少 (最小配置只要4Mb内存就能运行). 百度百 ...

  4. Shell基本运算符

    原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用. expr 是一款表达式计算工具,使用它能完成表达式的求值操作. 例如,两个数相加(注意使用 ...

  5. GatewayWorker + LayIM实现即时聊天

    一.程序目录结构 二.代码展示 附LayIM开发文档:https://www.layui.com/doc/modules/layim.html 1.前端代码 <!DOCTYPE html> ...

  6. 【转载】resolv.conf中search作用

    原文地址:http://www.oliver.ren/linux/387.html reslov.conf中的search主要是用来补全hostname的,有时候域名太长,可以做一个短域名做主机名字, ...

  7. [C++] 配平化学方程式算法的封装

    有人已经实现了配平的方法,在此不再重复介绍. https://www.cnblogs.com/Elfish/p/7631603.html 但是,上述的方法所提供的代码还是存在着问题,需要进一步修改. ...

  8. BZOJ 3572 [HNOI2014]世界树 (虚树+DP)

    题面:BZOJ传送门 洛谷传送门 题目大意:略 细节贼多的虚树$DP$ 先考虑只有一次询问的情况 一个节点$x$可能被它子树内的一个到x距离最小的特殊点管辖,还可能被管辖fa[x]的特殊点管辖 跑两次 ...

  9. 五、Scrapy中Item Pipeline的用法

    本文转载自以下链接: https://scrapy-chs.readthedocs.io/zh_CN/latest/topics/item-pipeline.html https://doc.scra ...

  10. 10.多shard场景下relevence score可能不准确

    主要知识点 多shard场景下relevence score可能不准确的原因 多shard场景下relevence score可能不准确解决方式     一.多shard场景下relevance sc ...