- 1、本文档共28页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
高质量C编程指南5
第五章、C++高级特性 5.1 类与对象 一、类是数据成员和函数成员的组合: 1、类中任何数据成员都不能用auto、extern、register关键字修饰。 2、如果程序中只出现类的定义,而未声明该类的实例—对象,则编译器不会给该类分配任何空间(静态成员除外)。 二、对象的内存映像 1、简单的非多态类 例:类Rectangle的声明如下: class Rectangle { public: Rectangle( ):m_length(1),m_width(1){ … } ~ Rectangle( ) { … } float GetLength( ) const { return m_length; } void SetLength(float length ) { m_length=length; } float GetWidth( ) const { return m_width; } void SetWidth( float width) { m_width= width; } void Draw( ) {…} static unsigned int GetCount( ) { return m_count;} protected: Rectangle(const Rectangle copy) {…} Rectangle operator=(const Rectangle assign) { … } private: float m_length; //长 float m_width; //宽 static unsigned int m_count; //对象计数 }; 该类对象模型有这样三个规则: (1)非静态数据成员被放在每一个对象体内作为对象专有的数据成员。 (2)静态数据成员被提取出来放在程序的静态数据区内为该类所有对象共享,因此仅存在一份。 (3)静态和非静态成员函数最终都被提取出来放在程序代码段中并为该类所有对象共享,因此每一个成员函数也只存在一份代码实体。 因此构成对象本身的只有数据,任何成员函数都不隶属于任何一个对象,非静态成员函数与对象的关系就是绑定,绑定的中介就是this指针。 成员函数为该类所有对象共享,不仅出于简化语言实现、节省存储的目的,而且是为了使同类对象具有一致的行为。同类对象的行为虽然一致,但是操作不同的数据成员。 下面是Rectangle类对象的内存映像 2、带有派生类的内存映像: 假设Rectangle派生自抽象类Shape,Shape有一个属性m_color,并且把Draw移到Shape中作为纯虚函数,如下所示: class Shape { public: Shape( ):m_color(0) { } virtual ~Shape( ) { } float GetColor( ) const { return m_color; } void SetColor(float color) {m_color=color;} virtual void Draw( )=0; private: float m_color; //颜色 }; 增加了继承和虚函数的类的对象模型变得更加复杂,规则如下: (1)派生类继承基类的非静态数据成员,并作为自己的专用数据成员。 (2)派生类继承基类的非静态成员函数,并像自己的成员函数一样访问。 (3)为每一个多态类创建一个虚函数指针数组vtable,该类的所有虚函数的地址都保存在这张表里。 (4)多态类的每一个对象(如果有)中安插一个指针成员vptr,其类型为指向函数指针的指针,它指向所属类的vtable;vptr就是C++对象的隐含数据成员之一,实际上它是被安插在多态类的定义中。 (5)为了支持RTTI,为每一个多态类创建一个type_info 对象,并把其地址保存在vtable中的固定位置(一般为第一个位置)。现在的Rectangle的对象模型如下: 这个模型有如下特点: (1)从一个派生类对象入手,可以直接访问到基类的数据成员,因为基类的数据成员被直接嵌入到派生类对象。 (2)不论派生层次有多深,派生类对象访问基类对象的数据成员和成员函数时,与访问自己的数据成员和成员函数没有任何效率差异。 (3)由于派生类数据成员和基类数据成员的这种紧密关系,当基类定义发生改变的时候(例如删除或增加成员),派生
文档评论(0)