第一章    关于对象

在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. Spring Cloud (13) 服务网关-路由配置

    传统路由配置 所谓传统路由配置方式就是在不依赖于服务发现机制情况下,通过在配置文件中具体制定每个路由表达式与服务实例的映射关系来实现API网关对外部请求的路由.没有Eureka服务治理框架帮助的时候, ...

  2. 研磨JavaScript系列(三):函数的魔力

    JavaScript的代码中就只有function一种形式,function就是函数的类型.在其他的编程语言中可能还存在Procedure或者是method等代码概念,在JavaScript中只有fu ...

  3. html5——2D转换

    transform 属性 1.向元素应用 2D 或 3D 转换 2.该属性允许我们对元素进行旋转.缩放.移动或倾斜. 缩放与位移 transform: scale(, 0.5);//水平缩放,垂直缩放 ...

  4. Python 时间处理---------笔记

    时区处理&格式化 import pytz from datetime import datetime # 设置时区 timezone = pytz.timezone('Asia/Shangha ...

  5. 【译】x86程序员手册00 - 翻译起因

    从上一次学习MIT的操作系统课程又过去了一年.上次学习并没有坚持下去.想来虽有种种原因,其还在自身无法坚持罢了.故此次再鼓起勇气重新学习,发现课程都已由2014改版为2016了.但大部分内容并没有改变 ...

  6. dubbo之优雅停机

    优雅停机 Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果用户使用 kill -9 PID 等强制关闭指令,是不会执行优雅停机的,只有通过 kill PID 时,才 ...

  7. CAD从二制流数据中加载图形(com接口)

    主要用到函数说明: _DMxDrawX::ReadBinStream 从二制流数据中加载图形,详细说明如下: 参数 说明 VARIANT varBinArray 二制流数据,是个byte数组 BSTR ...

  8. 微信小程序animation

    wxml <view class="background" animation="{{rotateData}}"> </view>< ...

  9. 解决windows64位系统上安装mysql-python报错

    解决windows64位系统上安装mysql-python报错 2018年03月12日 13:08:24 一个CD包 阅读数:1231    版权声明:本文为博主原创文章,未经博主允许不得转载. ht ...

  10. 关于panda中dataframe的与&运算*(stackoverflow高票答案)

    85 down vote favorite 31 What explains the difference in behavior of boolean and bitwise operations ...