`

深度探索C++ 对象模型--关于对象(阅读笔记)(原创)

 
阅读更多

                                        深度探索C++ 对象模型(阅读笔记)(原创)
                                                          Inside The C++ Object Model

 

                                                             --关于对象
由 王宇 原创并发布


让我肃然起敬并崇拜的牛人

       Bjarne Stroustrup    -  C++之父    (www.stroustrup.com)

       Stanley B. Lippman  -  本书作者、C++代言人、C++编译器的设计者之一

       侯捷                         -  本书译者   (jjhou.boolan.com)

第一章 关于对象

        C++在布局及存取时间上主要的额外负担是由virtual引起的。

         两个概念:

                  1) virtual function机制: 用以一种有效的“执行期绑定”(runtime binding)

                  2) virtual base class:    用以实现“多次出现在继承体系中的 base class, 有一个单一而被共享的实体”

1.1 C++对象模型(The C++ Object Model)

            类数据成员(class data memeber): 静态(static)和非静态的(nonstatic)

            类成员函数(class member function):静态(static)函数、非静态函数(nonstatic)和虚(virtual)函数 


 

           在C++对象模型中,Nonstatic data memeber 被配置与每一个class object之内,static data members则被存放在所有的class object之外,static和nonstatic function members也被放在所有的class object之外,virtual functions则以两个步骤支持之:

                      1、每个class产生出一堆指向virtual function的指针,放在表格之中。这个表格被成为virtual table(vtbl).

                      2、每个class object被添加了一个指针,指向相关的vitrual table.通常这个指针被称为vptr. vptr的设置和重置都由每一个class的constructor、destructor和copy assignment运算符自动完成。每一个class所关联的type_info object(用于支持runtime type identification,RTTI)也经由vitual talbe被指出来,通常是放在表格的第一个slot处。


             优点:它的空间和存取时间的效率

             缺点:如果应用程序代码本身未曾改变,但所用到的class object的nonstatic data memeber有所改变,那么那些应用程序代码同样得重新编译。

            对象模型如何影响程序:

                       class X 定义了一个copy constructor, 一个virtual destructor,和一个virtual function foo:
 

X foobar()
{
    X xx;
    X *px = new X;
    //foo() 是一个virtual function
    xx.foo();
    px->foo();

    delete px;
    return xxx;
}

 

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

void foobar(X &_result)
{
    ...
    //扩展xx.foo()但不使用virtual机制
    //以 _result 取代xx
    foo(&_result);

    //使用virtual机制扩展px->foo()
    ( *px->vtbl[ 2 ] )( px );
    ...
}

 

                    结论是

                                 以下方式不能使用virtual机制:

                                    X xx;
                                    xx.foo()

                                 以下方式可以使用virtual机制:

                                    X *px = new X;
                                    px->foo();

1.2 关键词所带来的差异

                 关键词的困扰:

                         在C++观念上,struct 是可以替代class的,但仍然声明public、protected、private等等存取区段。

                策略性正确的struct:

                        C程序员的巧计有时候却成为C++程序员的陷阱。例如把单一元素的数组放在一个struct的尾端,于是每个struct objects可以拥有可变大小的数组:

                  struct mumberl{
                                 /* stuff */
                                 char pc [1];
                   };

                       如果改用class来声明,在C++中凡处于同一个access section的数据,必定保证以其声明次序出现在内存布局当中,然而被放置在多个access section中的各笔数据,排列次序就不一定了,所以最好的忠告就是:不要那么做。

       
1.3 对象的差异:
   
                 C++ 程序设计模型直接支持三种程序设计典范(programming paradigms)

                        1)程序模型(procedural model),就像C一样

                        2)抽象数据类型模型(abstract data type model,ADT),该模型所谓的“抽象”是和一组表达式(public接
口)一起提供,而其运算定义任然隐而未明。

                        3)面向对象模型

                需要多少内存才能够表现一个class:

                      1)其nonstatic data members的总和大小

                      2)加上任何由于alignment的需求而填补上去的空间。(alignment就是将数值调整到某数的倍数。在32位计算机上,通常alignment为4bype,以使bus的“运输量”达到最高效率)(我在此处理解为对齐内存中的对象。)

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

              指针的类型:

                     寻址出来的object类型不同。也就是说,“指针类型”会教导编译器如何解释某个特定地址中的内存内容及其大小
   
                    例:

                           int    *p        地址:1000 - 1003
                           string *pstr  地址:1000 - 1015
                           viod   *pV    地址:指向1000,而地址空间我们不知道!这就是为什么一个类型为void*的指针只能够含有一个地址,而不能通过它操作所指之object的缘故。必须进行转型。

                     转型(cast)其实是一种编译器指令。大部分情况下它并不改变一个指针所含的真正地址,它只影响"被指出之内存的大小和其内容"的解释方式

                加上多态之后的布局:

    class Bear : public ZooAnimal{
        public:
            Bear();
            ~Bear();
            void rotate();
            virtual void dance();
        protected:
            enum Dances{ .. };
           
            Dances dances_known;
            int cell_block;  
    };

 

                             Bear b("Yogi");
                             Bear *pb = &b;
                             Bear &rb = *pb;

   

 

                             假设一:
                                        Bear b;
                                        ZooAnimal *pz = &b;
                                        Bear *pb = &b;

                                        差别是pb所涵盖的地址包含整个Bear object,而pz所涵盖的地址只包含Bear object中的ZooAnimal suboject

                                       除了virtual机制,pz不能指向Bear 中的函数
       
                                       pz的类型将在编译时期决定一下两点:
                                               (1)固定的可用接口,也就是说pz只能够调用ZooAnimal的public接口
                                               (2)该接口的access level
       
                              假设二:


                                        Bear b;
                                        ZooAnimal za = b;//这会引起切割(sliced)

                                         za.rotate();    //调用ZooAnimal::rotate();   
       
                                       为什么za的vptr不指向Bear的virtual table?

                                                za并不是(而且也绝不会是)一个Bear,它是(并且只能是)一个ZooAnimal。多态所造成的“一个以上的类型”的潜在力量,并不能够实际发挥在"直接存取 object"这件事情上。有一个似是而非的观念:OO程序设计并不支持对object的直接处理

                                      ZooAnimal za;
                                      ZooAniall *pza;
   
                                      Bear b;
                                      Panda *pp = new Panda;

                                      pza = &b;

   

 

   
                                        一个pointer或一个reference之所以支持多态,是因为它们并不引发内存中任何“与类型有关的内存委托操作(type-dependent commitment)”;会受到改变的只是他们所指向的内存的“大小和内容解释方式(参考上面的‘指针的类型’)”而已






 

  • 大小: 73.1 KB
  • 大小: 55.4 KB
  • 大小: 76.4 KB
分享到:
评论

相关推荐

    《深度探索C++对象模型(Inside The C++ Object Model )》学习笔记

    通过阅读《深度探索C++对象模型》的学习笔记,我们可以更深入地理解C++的底层机制,这对于成为一名精通C++的开发者来说是必不可少的。同时,结合《Effective C++》的学习,可以让我们写出更加高效、健壮的C++代码。...

    深度探索C++对象模型笔记.pdf

    本篇文章基于《深度探索C++对象模型笔记》的部分内容,对C++对象模型进行深入探讨。 #### 对象模型的基本概念 在C语言中,数据与处理数据的操作通常是分开的,通过一系列分布于不同函数中的算法来处理共享的外部...

    深度探索C++对象模型_读书笔记1

    《深度探索 C++对象模型》是一本深入剖析C++内部机制的著作,它揭示了C++如何在内存中表示和管理对象,以及由此产生的性能影响。通过对C++对象模型的了解,程序员可以编写出更高效、更少错误的代码。 在C++中,类是...

    深度探索C++对象模型(笔记)

    在深入探讨C++对象模型这一主题时,我们首先需要理解C++语言的核心概念,它是一种静态类型、编译式、通用的、大小写敏感、不支持自动垃圾回收的编程语言。C++以其强大的面向对象特性著称,这些特性包括封装、继承和...

    深度探索C++对象模型(二)

    深度探索C++对象模型(6)这是这个系列笔记的第7篇了,我们还在和构造函数打交道,以前写程序时怎么根本没有考虑过构造函数的事情呢?原来编译器为我们做了这么多的事情,我们都不知道.,要想完全搞明白,看来还需要一段...

    C++书籍阅读笔记

    本压缩包包含的是一系列关于C++的深度学习资料,包括阅读笔记,涵盖了多个核心主题,如C++的对象模型、STL的高效使用、C++中的陷阱和缺陷,以及虚函数和虚继承等关键概念。下面将对这些知识点进行详细阐述。 首先,...

    C++和Linux学习笔记.zip

    《C++与Linux系统编程深度探索》 C++是一种强大且通用的编程语言,它以其高效、灵活性和面向对象的特性被广泛应用于软件开发、游戏引擎、系统编程等多个领域。而Linux作为开源的操作系统,拥有丰富的开发环境和工具...

    front-note:书籍笔记

    在编程语言方面,笔记可能涉及Java、Python、C++或JavaScript等,包括它们的基本语法、面向对象编程、异常处理、数据结构和算法等核心主题。对于初学者,这些笔记将提供清晰的学习路径;对于经验丰富的开发者,它们...

    机器学习、深度学习

    深度学习是人工智能领域的一个重要分支,它通过模拟人脑神经网络的工作原理,让计算机..."deeplearningbook-chinese"文件名表明这可能是一本中文版的深度学习教材或笔记,涵盖上述知识点,适合初学者逐步掌握深度学习。

    《Qt5编程入门》笔记1

    Qt Quick的使用,QML的语法学习,Quick基础,控件和对话框的运用,图形动画的基础知识,图形效果的创建,粒子系统的构建,canvas的使用,模型和视图的概念,多媒体应用的开发,以及如何将QML与C++深度集成,使用...

    ROS-机器视觉trash:///robot-vision.zip 学习笔记(二)人脸识别和二维码识别

    这些算法通过提取人脸的关键特征并建立模型来进行识别。在实际应用中,我们需要创建一个ROS节点,捕获来自摄像头的图像,然后利用OpenCV进行预处理(如灰度化、直方图均衡化)、特征提取和匹配,最后将识别结果发布...

    学习笔记:学习笔记

    例如,Python的面向对象编程、Java的异常处理、C++的模板机制,或是JavaScript的异步编程模型。理解并掌握这些语言的特性有助于提高代码质量和效率。 2. 操作系统:操作系统是计算机的心脏,学习笔记中可能涵盖了...

    BMP位图格式自学笔记

    **BMP位图格式自学笔记** BMP(Bitmap)是一种常见的位图图像文件格式,广泛应用于Windows操作系统中。它以未经压缩的原始像素数据存储图像,使得BMP文件通常较大,但同时也保证了图片质量。BMP格式适用于学习图像...

    note:前置学习笔记

    【标题】: "前置学习笔记" 涵盖了在深入探索信息技术领域之前需要掌握的基础知识,这是一份全面的学习指南,旨在为初学者或有经验的IT从业者提供一个稳固的起点。这份笔记包含了计算机科学的基本概念、编程语言的...

    博客:对过往做做总结

    6. **Objective-C++/Jupyter Notebook**: Objective-C++是Objective-C和C++的结合,允许在Objective-C代码中使用C++特性。Jupyter Notebook则是一种交互式的计算环境,支持多种编程语言,如Python、R、Julia等,便于...

    2_to_student (模板,样例).zip

    3. **样例代码**:对于数据结构和算法的学习,压缩包可能包含各种算法的实现,如排序算法(冒泡排序、快速排序)、搜索算法(二分查找、深度优先搜索)等,通过阅读和修改这些代码,学生能加深对算法的理解。...

Global site tag (gtag.js) - Google Analytics