深度探索C++对象模型(阅读笔记)(原创)
Inside The C++ Object Model
--Data 语意学
由 王宇 原创并发布 :
让我肃然起敬并崇拜的牛人:
Bjarne Stroustrup - C++之父 (www.stroustrup.com)
Stanley B. Lippman - 本书作者、C++代言人、C++编译器的设计者之一
侯捷 - 本书译者 (jjhou.boolan.com)
第三章 Data 语意学
3.1 Data Member的绑定
例:
extern float x; class Point3d { public: point3d(); //问题:被传回和被设定的x是哪一个x呢? float X() const { return x; } private: float x, y, z;//Point3d::X()将返回内部的x。 };
在早期(2.0之前)C++的编译器上,将会指向global x object, 导致C++的两种防御性程序设计风格:
1、把所有的data members放在class 声明起头处,以确保正确的绑定
2、把所有的inline functions, 不管大小都放在class声明之外
对于 member function的argument list并不为真(同以上情况相反)。
例:
typedef int length; class Point3d { public: //length 将被决议为global //_val将被决议为Point3d::_val void mumbel(length val) { _val = val; } length mumble() { return _val; } private: //导致 _val = val; return _val;不合法 typedef float length; length _val; };
预防性程序风格:请始终把“nested type 声明”放在class的起始处。
3.2 Data Member的布局
Nonstatic data member 在class object中的排列顺序将和其被声明的顺序一样,任何中间介入的static data members 如 freelist 和 chunkSize都不会被放入对象布局中
传统上vptr放在所有明确声明member之后
3.3 Data Member的存取
Point3d origin, *pt = &origion;
origin.x = 0.0;
pt->x = 0.0;
这两种方式的差异?
Static Data Members:
结论是完全相同, 原因是:每一个static data member 只有一个实体, 存放在程序的data segment之中, member其实并不在class object之中。
Nonstatic Data Members:
结论是完全相同,原因是:
pt->x = 0.0; 方式:事实上是经由一个“implicit class object”(由this指针表达)完成
//member function 的内部转化
Point3d
Point3d::translate( Point3d *const this, const Point3d &pt)
{
this->x = pt.x;
}
origin.x = 0.0; 方式:class object的起始地址加上data member的偏移量(offset)
&origin + (&Point3d::_y - 1);
3.4 "继承"与 Data Member
一个derived class object所表现出来的东西, 是其自己的member加上其base class(es) members的总和。图3.1b
只要继承不要多态
继承易犯的错误:
(1)重复设计一些相同的操作函数
(2)把一个class分解为两层或更多层,有可能会为了“表现class体系之抽象化”而膨胀所需空间。(因为类型对齐,会浪费空间) 图p105
填充空间的原因是为了复制对象时,避提高效率,免产生偏差。
加上多态
空间和存取时间的额外负担:
(1)导入一个virtual table 和一个vptr
(2)加强constructor 和distructor 使其能够初始化和抹消virtual table和vptr 。
把vptr放置在class object的那里会最好?
(1)放在尾部保留C struct 的对象布局,C++最初期,这种方式被许多人采用。
(2)放在前端,对于“在多重继承之下,通过指向class members的指针调用virtual function”,会带来一些帮助。当然代价就是丧失了C语言兼容性。
多重继承
多重继承的复杂度在于derrived class 和其上一个base class乃至于上上一个base class...之间的“非自然”关系。参考下列代码:
class Point2d { public: protected: float _x, _y; }; class Point3d : public Point2d { public: protected: float _z; }; class Vertex { public: protected: Vertex *next; }; class Vertex3d : public Point3d, public Vertex { public: protected: float mumble; };
下列操作并不需要编译器去调停或修改地址,它很自然地可以发生,而且提供了最佳执行效率。
Point3d p3d;
Point2d *p = &p3d;
多重继承的问题主要发生于derived class object 和其第二或后续的base class object之间的转换:
Vertex3d v3d;
Vertex *pv;
Point2d *p2d;
Point3d *p3d;
pv = &v3d;
// 需要这样的内部转换:
pv = (Vertex*)(((char*)&v3d) + sizeof(Point3d));
// 下列转换只需要简单地拷贝地址就行了
p2d = &v3d;
p3d = &v3d;
参考图:3.4 p115
C++ Standard 并未要求Vertex3d中的base classes Point3d和Vetex有特定的排列次序。原始的cfont编译器是根据声明次序来排序它们。目前各编译器仍然是以此方式完成多重base classes的布局(但如果加上虚拟继承,就不一样了)
虚拟继承
多重继承的一个语意上的副作用就是,它必须支持某种形式的“shared subobject继承”。参考图p117
不论是istream或ostream都内含一个ios subobject。然而在iosstream的对象布局中,我们只需要单一一份ios subobject就好。语言层面的解决办法是导入所谓的虚拟继承
3.5 对象成员的效率
应该确实地测量效率,而不是靠着推论与常识判断。
3.6 指向Data Members的指针
class Point
{
public:
virtual ~Point();
static Point origion;
float x,y,z;
};
如果vptr放在对象的尾端,则三个坐标值在对象布局中的offset分别是0,4,8。如果vptr放在对象的起头,则三个坐标值在对象布局中的offset分别是4,8,12.然而你若去取data members的地址, 传回的值总是多1, 就是1,5,9,或5,9,13
如何区分一个“没有指向任何data member”的指针和一个指向“第一个data member”的指针?考虑下列例子:
Point3d p3d;
Point3d *p1 = 0;
Point3d *P2 = &p3d;
if( p1 == p2){};
为了区分p1 和p2 ,每一个真正的member offset值都被加上1. 因此,无论编译器或使用者都必须记住,在真正使用该值以指出一个member之前,请先减掉1。
相关推荐
在深入探讨《深度探索C++对象模型》这一主题之前,我们首先需要理解C++对象模型的基本概念及其在程序设计中的重要性。C++作为一种广泛使用的编程语言,其强大的功能和灵活性使得它成为许多领域的首选语言之一。对于...
《深度探索C++对象模型》是一本专注于C++编程语言底层机制的专业书籍,它深入剖析了C++的对象模型,帮助读者理解C++是如何在内存中表示对象、如何实现继承、多态等特性。这本书的内容涵盖了C++的核心概念,包括类、...
《深度探索C++对象模型》专注于C++面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟——虚拟函数和虚拟继承。这本书让你知道:一旦你能够了解底层实现模型,你的程序代码将获得...
《深度探索C++对象模型》是一本专注于C++底层机制的专著,主要针对2012年的标准进行深入解析。C++是一种多范式、静态类型、编译型、并发型、通用程序设计语言,它以其强大的功能和灵活性而闻名。这本书的目标是帮助...
深度探索C++对象模型 超高清
### 深度探索C++对象模型:理解与解析 #### C++对象模型概览 C++对象模型是C++编程语言中一个核心且复杂的概念,它定义了如何在内存中表示类、对象以及它们之间的关系。理解C++对象模型对于深入掌握C++语言特性、...
在探索C++对象模型之前,首先需要理解对象模型(Object Model)的含义。对象模型是面向对象编程(Object-Oriented Programming,OOP)中的一个核心概念,它描述了对象的结构、属性、方法、以及对象之间的关系。C++...
深度探索C++对象模型 中文图片影印版pdf,比较清晰,不是那种模糊的版本,和文字版差别不大 英文清晰文字版chm 第一代C++编译器开发主管所写。如果你想成为真正的C++高手,看这本书,他为你讲述了编译器在处理各种...
深度探索C++对象模型 第0章 导读(译者的话) 第1章 关于对象(Object Lessons) 加上封装后的布局成本(Layout Costs for Adding Encapsulation) 1.1 C++模式模式(The C++ Object Model) 简单对象模型(A Simple...
深度探索C++对象模型 PDF中文清晰版.zip深度探索C++对象模型 PDF中文清晰版.zip深度探索C++对象模型 PDF中文清晰版.zip深度探索C++对象模型 PDF中文清晰版.zip深度探索C++对象模型 PDF中文清晰版.zip深度探索C++对象...
本书重点:探索“对象导向程序所支持的C++对象模型”下的程序行为。对于“对象导向性质之基础实现技术”以及“各种性质背后的隐含利益交换”提供一个清楚的认识。检验由程序变形所带来的效率冲击。提供丰富的程序...
《深入探索C++对象模型》是一本深度剖析C++编程语言内部机制的著作,而设计模式则是软件工程中的一种最佳实践,是解决常见问题的模板。这两者结合在一起,为开发者提供了理解C++如何实现面向对象特性以及如何高效地...
通过阅读《深度探索C++对象模型》的学习笔记,我们可以更深入地理解C++的底层机制,这对于成为一名精通C++的开发者来说是必不可少的。同时,结合《Effective C++》的学习,可以让我们写出更加高效、健壮的C++代码。...
总的来说,"深度解析C++对象模型"涵盖了C++语言中的核心概念,如类、对象、继承、多态、内存管理和模板,这些都是理解和编写高效C++代码的基石。通过深入学习和实践,开发者可以更好地掌握C++的精髓,编写出更加健壮...
通过阅读《深度探索C++对象模型》,读者能够深入了解C++语言的底层机制,提升编程技能,更好地理解和调试复杂的C++代码。无论是对C++感兴趣的开发者,还是致力于成为C++专家的程序员,这本书都是不可或缺的参考文献...