深度探索C++对象模型 1

第一章:关于对象

 

加上封装后的布局:

如果C++class和C struct含有相同数据成员,那么C++class并没有增加成本。因为,C++ class中的成员函数不出现在object中(non-inline 成员函数只会诞生一个实例,而inline函数则会在调用该C++ Class的文件模块中产生一个实例),所以C++支持的封装性质并未带来任何空间或执行期的不良后果。

 

C++在布局以及存取时间上主要的额外负担是由virtual引起的(包括虚函数机制和虚基类),此外多重继承下也会有额外负担(发生在一个子类和它的第二个或后继基类之间的转换时)。

 

1.1C++对象模型(书中写的是模式)

C++包含两种数据成员(static和nonstatic)和三种成员函数(static,nonstatic和virtual)。

 

C++对象模型:

Bjarne Stroustrup博士(C++之父,C++语言的创始人,著有《The C++ Programming Language》,《The Design and Evolution of C++》)将Nonstatic data members放在每一个classobject内,static data members放在class object之外,static和nonstatic function members也放在class object之外。virtualfunctions则以两个步骤支持:1.每个class产生出一堆指向virtual functions的指针,放在表格之中,这个表格成为 virtual table(简称vtbl)。2.每个class object被安插一个指针(称为vptr),指向相关的virtual table。vptr的设定和重置都由每一个class的constructor、destructor和copy assignment运算符自动完成(第五章讨论)。每一个class所关联的type_info object(用以支持runtime type identification, RTTI)也经常由virtual table被指出来,通常放在表格的第一个slot。

例如有以下一个类Point:

class Point{

public:

         Point(floatxval);

         virtual~Point();

        

         floatx() const;

         staticint PointCount();

private:

         virtualostream&

                   print(ostream &os ) const;

        

float _x;

static int_point_count;

} ;

则下图表示C++ 对象模型应用在Point类上。


这个模型的主要优点在于空间和存取时间的效率;缺点是如果应用程序代码本省未曾该表,但所用到的class object的nonstatic data member有所改变,那么那些应用层序也得重新编译。

 

加上继承:

C++最初采用的继承模型并不运用任何间接性:base class subobject的data members被直接放置于derived classobject中。优点:提供base class members最紧凑而且最有效率的存取;缺点:baseclass members的任何改变,任何用到该base class或该base class的derivedclass object都需要重新编译。

 

C++2.0之后导入virtualbase class,需要一些间接的base class表现方法:virtual base class的原始模型在classobject中为每一个有关联的virtual base class加上一个指针,或者在classobject中导入virtual base class table,又或者扩充原已存在的virtual table,以便维护每一个virtualbase class的位置。

 

对象模型如何影响程序:

不同的对象模型会导致“现有的程序代码必须修改”以及“必须加入新的程序代码”两个结果。

例如下面这个函数,其中class X定义了一个copy contructor、一个virtualdestructor和一个virtual function foo:

X foobar(){

         X xx;

         X *px = new X;

        

         //foo()是一个虚函数

         xx.foo();

         px->foo();

        

         delete px;

         return xx;

};

这个函数有可能在内部转化为:

Void foobar( X &_result ){  //此处&为引用

 

         //构造_result

_result.X::X();

        

//扩展X *px = new X;

px = _new( sizeof( X ) );

if( px != 0 )

         px->X::X();

 

//扩展xx.foo() 但不使用virtual机制

foo(& _result);                   //此处&为取地址符

 

//使用virtual扩展px->foo()

( *px->vtbl[ 2 ] )( px  );

 

//扩展delete px;

( *px->vtbl[ 1 ] )( px );

_delete( px );

 

return;

}

下图可解决 *px->vtbl[ 1 ] 和 *px->vtbl[2 ] 的含义。

 

1.2  关键词所带来的差异

 

1.3对象的差异:

C++程序支持三种模型

1. 程序模型:像C程序一样

2. 抽象数据类型模型(也被称为object-based OB):有封装,但没有多态和继承。比如string

3. 面向对象模型(object- oriented OO):有封装,多态,继承

 

C++以下列方式支持多态:

1.由一组隐式的转化操作:父类指针指向子类对象,或父类引用类型引用子类对象

2.经由虚函数机制

3.经由dynamic_cast和typeid运算符

 

一个class object需要的内存一般而言由三部分组成:

1.      其nonstatic data members的总和大小(包括父类的nonstaticdata members)

2.      加上任何由于alignment而需要的填充空间。(alignment就是将数值调整到某数的倍数。在32位计算机上,alignment为4bytes,以使运算量达到最高效率)

3.      加上为了支持virtual而由内部产生的任何额外负担

 

指针的类型:

“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小。

如:有一个对象有两个数据成员,类型分别为int和string,还有一个指向该对象的指针,则该指针将涵盖12bytes内存空间。(因为int占四个,string占8个包括一个字符指针和一个表示长度的整数);如果该对象有虚函数,则指向该对象的指针还要加4bytes,因为该对象会含有一个vptr指针。

我们不知道void*指针将涵盖怎样的地址空间,这就是void*只能够支持一个地址,而不能够通过它操作所指object的原因。

 

加上多态之后:

用一个父类指针指向一个子类对象,则这个指针所涵盖的地址只包含子类对象中的父类部分。可以用dynamic_cast和static_cast将父类指针转换为子类指针。

一个指针或引用之所以支持多态,是因为它们并不引发内存中任何“与类型有关的内存委托操作”;会受到改变的,只有它们所指向对象的内存的“大小和内容的解释方式”。

然而,如果将子类对象赋值给父类对象,子类对象的子类部分会被切割,父类部分保留。于是多态不在呈现。而一个严格的编译器可以在编译时期解析虚函数,但编译时期的虚函数为静态虚函数,也就是父类的虚函数,所以回避了virtual机制(在运行期解析的虚函数为指针所指对象的虚函数)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《深度探索C++对象模型》是由侯捷所著的一本经典的C++图书,该书于2012年由机械工业出版社出版。本书的主要内容涵盖了C++对象模型的深入解析和探讨。 在书中,作者详细讲解了C++中的对象模型和相关的概念,如类、对象、继承、多态等。作者首先介绍了C++对象模型的基本概念和特点,包括对象的内存布局、虚函数表和虚函数指针等。然后,作者深入探讨了C++中的继承机制和多态性,包括单继承、多继承、虚继承等。作者还详细介绍了虚函数的实现原理和使用方法。 在书中,作者对C++对象模型的实现细节进行了深入的剖析,包括成员变量和成员函数的内存布局、函数指针和成员函数指针的用法等。同时,作者还讨论了C++中的一些高级特性,如模板、内存管理和异常处理等。通过对C++对象模型深度探索,读者可以更好地理解C++的内部机制和原理,提高程序设计和开发能力。 《深度探索C++对象模型》适合具有一定的C++编程基础的读者阅读,尤其是对C++对象模型感兴趣的读者。通过阅读本书,读者可以进一步了解C++的底层实现和运行机制,从而提高自己的编程能力和代码质量。此外,本书还提供了大量的示例代码和实践案例,可以帮助读者更好地理解和应用所学知识。 总之,《深度探索C++对象模型》是一本深入探讨C++对象模型的经典著作,通过对C++的底层实现和内部机制的剖析,帮助读者深入理解C++编程语言,并提高自己的软件开发能力。 ### 回答2: 《深度探索C++对象模型》是由Stanley B. Lippman于1994年所著的一本经典畅销的C++书籍,该书详细介绍了C++对象模型的内部实现细节。 C++对象模型是指C++编译器在处理对象、继承、多态等面向对象特性时所采用的具体实现方式。这本书通过对对象模型的剖析,帮助读者深入理解C++的内部工作原理,从而写出更高效、更可靠的C++代码。 在《深度探索C++对象模型》中,作者首先介绍了对象、虚函数、继承等C++核心概念,然后详细讲解了C++对象模型的构建过程,包括对象布局、成员函数指针、虚函数表等。作者逐步深入地剖析了C++对象模型在内存中的表示方式,解释了为什么C++可以支持如此强大的面向对象特性。 此外,本书还探讨了一些高级主题,如多重继承、虚拟继承、构造函数和析构函数的执行顺序等。对于想要深入学习C++的读者来说,这本书提供了一些宝贵的技术手册和实用的经验。 尽管《深度探索C++对象模型》的出版时间是1994年,但它仍然被广泛认可为学习C++对象模型的经典之作。在2012年时,由于C++的发展和演进,也许一些内容已经有些过时,但很多基本概念和原理仍然适用。 总而言之,《深度探索C++对象模型》是一本值得阅读的C++经典著作,通过深度探索C++对象模型,读者可以更加深入地了解C++的内部工作原理和实现方式,提升自己的开发技能。 ### 回答3: 《深度探索C++对象模型》是一本于2012年出版的书籍。该书的作者Andrews和Sorkin以全面的角度深入探讨了C++对象模型。该书重点介绍了C++中的对象表示、虚函数、继承、多重继承、构造函数、析构函数等内容,以及与之相关的语法、原理和底层实现。 这本书为读者揭示了C++对象模型的奥秘,让人更加深入地理解C++语言中的类和对象。作者通过分析对象布局、虚函数表、虚函数调用、多继承中的数据布局和函数调用等等,解释了C++对象模型的实现机制。 在读者了解C++对象模型的基础上,该书还介绍了如何有效地利用对象模型来提高程序的性能。作者讨论了虚函数的成本以及如何减少虚函数调用的开销,提供了一些优化技巧。此外,书中还对C++的构造函数和析构函数进行了深入的讨论,详细解释了构造函数和析构函数的执行机制和注意事项。 总的来说,《深度探索C++对象模型》是一本深入剖析C++对象模型的重要参考书籍。通过阅读该书,读者可以更加全面地了解C++的类和对象的实现原理,对于理解C++语言的底层机制和优化程序性能具有积极的作用。无论是对于初学者还是有一定C++基础的开发人员来说,该书都是一本值得阅读的重要参考书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值