深度探索C++对象模型
文章平均质量分 91
读深度探索C++对象模型这本书的读后感和笔记。
扮猪吃饺子
努力的人,运气不会太差。
展开
-
7.4 效率有了,弹性呢?
传统的C++对象模型提供了有效率的执行期支持。这份效率,再加上与C之间的兼容性,造成了C++的广泛被接受度。然而在某些领域方面,像动态共享函数库、共享内存以及分布式对象方面,这个对象模型的弹性还不够。动态库理想中,一个动态链接库应该像“突然造访”一样,当应用程序下一次执行时,会透明化地取用新的库版本,新的库不应该对旧的应用程序产生侵略性。在目前的C++对象模型中,如果新版本的library...原创 2018-12-18 06:59:39 · 109 阅读 · 0 评论 -
7.3 执行期类型识别(Runtime Type Identification,RTTI)
Type-Safe Downcast(保证安全的向下转换操作)C++被吹毛求疵的一点,它缺乏一个保证安全的downcast(向下转换操作)。只有在“类型真的可以被适当转换”的情况下,你才能够执行downcast。一个type-safe downcast必须在执行期对指针所有查询,看看它是否指向它所展现之object真正的类型。因此,欲支持type-safe downcast,在object空间...原创 2018-12-18 06:39:25 · 495 阅读 · 0 评论 -
7.2 异常处理(Exception Handing)
Exception Handing快速检阅C++的exception handing由三个主要语汇组件构成:一个throw子句。它在程序某处发出一个exception,被抛出去exception可能是内建类型,也可是自定义类型。 一个或多个catch。每个catch子句都是一个exception handler,它用来表示这个子句准备处理某种类型的exception,并且在封闭的大括号内...原创 2018-12-14 07:08:58 · 533 阅读 · 0 评论 -
7.1 Template
原来Template被视为对container classes如Lists和Arrays的一项支持,但现在它已经成为标准模板库(STL)的基础。它也被用于属性混合(如内存策略)或互斥(mutual exclusion)机制的参数化技术之中。它甚至被使用与一项所谓的template metaprgrams:class expression templates将在编译时期而非执行期被评估,因为带来重大...原创 2018-12-12 07:29:22 · 211 阅读 · 0 评论 -
6.3 临时性对象(Temporary Objects)
如果我们有一个函数,以及两个T object,a和b:T operator+(const T&,const T&);a+b;那么可能导致一个临时对象,以放置传回的对象。是否导致一个临时对象,视编译器的进取性(aggressiveness)以及上述操作发生的程序语境(program context)而定。例如:T a,b;T c = a+b;1.编译器可能产...原创 2018-12-10 06:41:56 · 446 阅读 · 0 评论 -
6.2 new和delete运算符
运算符new的使用,事实上经过两个步骤完成:int* pi = new int(5);//1.通过new运算符,配置所需要的内存int* pi =_new(sizeof(int));//2.将配置的对象设立初值*pi = 5; 更进一步说,初始化操作应该再内存成功(经由new运算符)后才执行://new运算符的两个分离步骤//int* pi = new int(5);...原创 2018-12-07 06:38:35 · 152 阅读 · 0 评论 -
6.1 对象的构造和析构(Object Costruction and Destruction)
一般而言,constructor和destructor的安插如你所预期那样://C++ pseudo{ Point point; //point.Point::Point(); 一般会被安插在这里 ... //point.Point::~Point(); 一般会被安插在这里}如果一个区间(以{}括起来的区间)或函数中有一个以上的离开点,情况会稍微复杂点。Destructor...原创 2018-12-04 08:02:00 · 168 阅读 · 0 评论 -
第六章 执行期语意学(Runtime Semantics)
想象下简单的式子:if(yy == xx.getValue()) ...//xx 和 yy的定义X xx;Y yy;//Y定义class Y{public: Y(); ~Y(); bool operator ==(const Y&) const; //...};//X定义class X{public: X(); ~X(); operato...原创 2018-11-30 07:14:31 · 186 阅读 · 0 评论 -
5.5 析构语意学(Semantics of Destruction)
如果class没有定义destructor,那么只有在class内含的member object(或class自己的base class)有拥有destructor时,编译器才会自动合成一个出来。否则,destructor被视为不需要,也就不需要合成(当然更不需要调用)。例如,Point,默认情况下并没有被编译器合成一个destructor——甚至虽然它拥有一个virtual function...原创 2018-11-30 06:55:08 · 153 阅读 · 0 评论 -
5.4 对象的效能(Object Efficiency)
以下的效率测试中,对象构造和拷贝所需的成本是以Point3d class声明为基础,从简单形式逐渐到复杂形式,包括Plain OI' Data、抽象数据类型(ADT)、单一继承、多重继承、虚拟继承。以下是测试的主角:Point3d lots_of_copies(Point3d a,Point3d b){ Point3d pC = a; pC = b;//(1) b = a; //...原创 2018-11-28 07:17:21 · 143 阅读 · 0 评论 -
5.3 对象复制语意学(Object Copy Semantics)
当我们设计一个class,并以一个class object赋值给另一个class object时,我们就用到了拷贝复制操作,我们可以选择默认的浅拷贝,也可以自己提供一个explicit copy assignment operator,或者显示的拒绝把一个class object赋值给另一个class object(将copy assignment operator声明为private)。为了...原创 2018-11-27 07:34:15 · 192 阅读 · 0 评论 -
5.2 继承体系下的对象构造
当我们定义一个object如下:T object;如果T有一个constructor(不论是由user提供还是编译器合成的),它会被调用。Constructor可能内含大量的隐藏码,因为编译器会扩充每一个constructor,扩充视class T的继承体系而定。一般编译器所做的扩充操作大约如下:记录在member initialization list中的data member...原创 2018-11-26 07:29:40 · 140 阅读 · 0 评论 -
5.1 “无继承”情况下的对象构造
考虑如下的程序片段:Point global; //1Point foobar(){ Point local; //2 Point* head = new Point; //3 *head = local; //stuff delete heap; //4 return local;}上述表现出三种不用的对象产生方式:global对象、local对象和heap对象。...原创 2018-11-21 07:32:58 · 152 阅读 · 0 评论 -
第五章 构造、析构、拷贝语义学
如下一个abstract base class声明:class Abstract_base{public: virtual ~Abstract_base() = 0; virtual void interface() const = 0; virtual const char* mumble() const {return _mumble;}protected: char*...原创 2018-11-20 06:45:18 · 154 阅读 · 0 评论 -
4.5 Inline Functions
一般而言,处理一个inline函数,有两个阶段:分析函数定义,以决定函数的“intrinsic inline ability”(本质的inline能力)。如果函数因其复杂度,或因其构建问题,被判断不可成为inline,它会被转为一个static函数,并在“被编译模块”内产生对函数的定义。真正的inline函数扩展操作是在调用那一点上。这会带来参数的求值操作(evaluation)以及临时...原创 2018-11-16 07:00:13 · 172 阅读 · 0 评论 -
4.4 指向Member Function 的指针
取一个nonstatic data member的地址,得到的结果该是member在class布局中的bytes位置(再加1);它是一个不完整的值,它需要被绑定在某个class object的地址上,才能够被存取。取一个nonstatic data function地址,如果该函数是nonvirtual,得到的结果是它在内存中真正的地址。这值也是不完整的,也需要被绑定某个class objec...原创 2018-11-15 07:01:10 · 173 阅读 · 0 评论 -
4.3 函数的效能
在如下这组测试中,在不同编译器计算两个3D点,其中用到了一个nonmember friend function,一个member function,以及一个virtual member function,兵器virtual member function分别在单一、虚拟、多重继承三种情况下执行。如下是nonmember function:void cross_product(const Po...原创 2018-11-13 06:44:04 · 219 阅读 · 0 评论 -
4.2 Virtual Member Functions(虚拟成员函数)
单一继承下的Virtual Functions为了支持virtual function机制,必须首先能够对于多态对象有某种形式的“执行期类型判断法(runtime type resolution)”。如下的调用操作将需要ptr在执行期的某些相关信息,如此一来才能找到并调用z()的适当实例:ptr->z();或许最直接了当但是成本最高的解决方法就是把必要的信息加在ptr身上。在这...原创 2018-11-09 07:20:32 · 388 阅读 · 0 评论 -
4.1 Member 的各种调用方式
C++支持三种类型的member functions:static、nonstatic和virtual,每一种被调用的方式都是不同的。确定一个类成员函数不是为static:1、它能直接存取nonstatic数据;2、它被声明为const。static member functions不可能做到这两点。Nonstatic Member Functions(非静态成员函数)C++的设计准则之一...原创 2018-11-06 07:27:20 · 737 阅读 · 0 评论 -
3.6 指向Data Members的指针
指向Data Members的指针有两个用处:第一,可以调查class members的底层布局;第二。可以用来决定class 中的accesss section的顺序。考虑如下的Point3d的声明。其中有一个virtual function,一个static data member,以及三个坐标值:class Point3d{public: virtual Point3d();...原创 2018-11-02 10:43:24 · 402 阅读 · 0 评论 -
3.5 对象成员的效率(Object Member Efficiency)
以下对于局部变量、局部数组、C struct 和C++ 封装的函数进行测试,下列是两种编译器列出的各种结果:上述所显示的重点在于,如果把优化打开,“封装”就不会带来执行期的效率成本。使用inline存取函数亦然。在下一个测试中,使用单一继承、虚拟继承(单层)和虚拟继承(双层)的测试结果:class Point1d{...}; //维护xclass Point2d: public...原创 2018-11-01 07:35:18 · 203 阅读 · 0 评论 -
3.4 “继承”与Data Member
在C++继承模型中,一个derived class object 所表现出来的的东西,是其自己的members加上其base classes members的总和。至于derived class members和base classes members排列顺序并没在C++ Standard中强制规定:理论上编译器可以自由安排。在大部分编译器,base classes members在前面,但属于v...原创 2018-11-01 06:58:24 · 189 阅读 · 0 评论 -
3.3 Data Member 的存取
已知如下的代码:Point3d origin;origin.x = 0.0;对于x的存取的成本,视x和Point3d如何声明而定。x可能是个static member,也可能使个nonstatic member。Point3d可能是独立的(非派生)的class,也可能是从另一个单一的base class派生而来;甚至可能从多重继承或虚拟继承而来。对于通过类对象和指针来存取x,也会有...原创 2018-10-25 08:11:54 · 257 阅读 · 0 评论 -
3.2 Data Member的布局(Data Member Layout)
已知下面一组data member:class Point3d{public: //...private: float x; static List<Point3d*>* freeList; float y; static const int chuckSize = 250; float z;};Nonstatic data members在class o...原创 2018-10-24 08:18:46 · 132 阅读 · 0 评论 -
3.1 Data Member的绑定(The Bindling of a Data Member)
对于如下的钻石继承(菱形继承):class X{};class Y: public virtual X{};class Z: public virtual X{};class A: public Y,public Z{};上述X,Y,Z,A中没有任何的一个class内含明显的数据,其间表示了继承关系,每个class的大小都不会为0,即使是class X的大小也不会为0(机器有关...原创 2018-10-23 16:29:03 · 203 阅读 · 0 评论 -
2.4 成员们的初始化队列(Member Initialization List)
当你写下一个constructor时,就有机会设定class members的初值。为了让程序能够被顺利编译,有4种情况你必须使用member initialization list:当初始化一个reference member时; 当初始化一个const member时; 当调用一个base class的constructor,而它有用一组参数时; 当调用一个member class ...原创 2018-10-19 11:16:38 · 496 阅读 · 0 评论 -
2.3 程序转化语义学(Program Transformation)
显示的初始化操作(Explicit Initialization)已知有这样的定义:X x0;下面的三个定义,每一个都明显地以x0来初始化其class object:void foo_bar(){ X x1(x0); //定义了x1 X x2 = x0; //定义了x2 X x3 = X(x0); //定义了x3}必要的程序转化有两个阶段:重写每一个定义,...原创 2018-10-11 11:00:41 · 423 阅读 · 0 评论 -
2.2 Copy Constructor的构造操作
有三种情况,会以一个object的内容作为另一个class object的初始值。最明显的第一种情况当然就是对一个object做显示的初始值操作:class X{...};X x;//显示以一个object的内容作为另一class object的初值X xx = x;另两种情况是当objectbei当做参数交给某个函数时,例如:extern void foo(X x);v...原创 2018-09-27 10:33:54 · 274 阅读 · 0 评论 -
2.1 Default Constructor 的构造操作
“default constructors...在需要的时候被编译器产生出来“。被谁需要?做什么事情?看如下代码:class Foo{public: int val; Foo* pnext;};void foo_bar(){ //程序要求bar’s members都被清零 Foo bar; if(bar.val || bar.pnext) //...do someth...原创 2018-09-21 10:20:53 · 307 阅读 · 0 评论 -
1.3 对象的差异(An Object Distinction)
C++程序设计模型直接支持三种programming paradigms(程序设计范式)。 程序模型(procedural model)。就像C一样,C++当然也支持它。字符串的处理就是一个例子,我们可以像使用字符数组以及str*函数族群(定义在标准的C函数库中): char boy[] = "Danny";char* p_son;...p_son = new char[strl...原创 2018-09-19 10:26:23 · 206 阅读 · 0 评论 -
1.2 关键词所带来的差异(A Keyword Distinction)
如果不是为了努力维护与C之间的兼容性,C++远比现在更简单些。如果C++并不需要支持C原有的struct,那么class的观念可以借由关键词class来支持。但是,从C迁徙到C++,除了效率,另外一个最长被程序员问道的问题就是:什么时候一个人应该再C++程序中以struct取代class?关键词的困扰答案之一是:当它让一个人感觉比较好的时候。这个答案之处一个重要的特性:关键词str...原创 2018-09-17 10:16:50 · 310 阅读 · 0 评论 -
1.1 C++对象模式(The C++ Object Model)
C++在布局以及存取时间上主要的额外负担是由virtual引起的,包括:virtual function 机制 :用以支持一个有效率的“执行期绑定”(runtime binding)。 virtual base class :用以实现“多次出现在即成体系中的base class ,有一个单一而被共享的实体”。此外,还有一些多重继承下的额外负担,发生在“一个derived class 和其...原创 2018-09-13 10:54:09 · 392 阅读 · 0 评论