C++支持三种类型的member functions: static、nonstatic和virtual,每一种类型调用方式都不相同。

一 nostatic members functions
1 调用方式
   C++的设计原则之一就是:nonstatic member function知识和一般的nonmember function有相同的效率。因此:
    nonstatic member function被编译器内化为nonmember function的形式,且含有一个this(A *const this)指针成员。 
转化步骤如下:
① 改写函数的signature以安插一个额外的参数到member function,该参数即 this指针。
non-const nonstatic member增加:A *const this; const nonstatic member增加: const A *const this.
② 将每一个“对nonstatic data member的存取操作”改为经由this指针来存取。
③ 将member function重写成一个外部函数,对函数名称进行“name-mangling"处理,使它在程序中称为独一无二的词汇。
2 指向这类成员函数的指针
    取一个nonstatic member function的地址,如果该函数是nonvirtual,得到的结果是它在内存中真正的地址,然而这个值也是不完全,它也需要被绑定于某个class object地址上,才能够通过它调用该函数。所有的nonstatic member function 都需要对象的地址(以参数this 指出)。
二 static member function
1 调用方式
    static member function被编译器转化为nonmember function的形式,且不含this指针成员。
static member function的主要特性就是它没有this指针,以下的次要特性统统根源与其主要特性:
① 它不能直接存取其class中nonstatic members
② 它不能被声明为const,volatile或virtual。
③ 它不需要经由class object才能调用--虽然大部分时候它是这样调用的。
2 指向这类成员函数的指针
    取一个static member function地址,获得的将是其在内存中的位置,也就是地址。由于没有this指针,所以其地址的类型并不是一个指向”class member function “ 指针,而是一个”nonmember“ 函数指针。
三 virtual member functions 
调用方式:
1 virtual function的一般实现模型:① 每一个class有一个virtual table,内涵该class 之中有作用的virtual function的地址,②然后每个object有一个vptr,指向virtual table的所在。
2 ptr->z(); z()是虚函数,我们在执行期需要知道:
① ptr所指对象的真实类型,这可使我们选择正确的z()实体。(表示类型信息的字符串或数字)
② z()实体位置,以便我们能够调用它。通过虚函数指针(指向虚函数表)+该函数表格索引值。
3 virtual table中虚函数地址如何构建起来。
    在C++中,虚函数地址可以在编译时期获得,此外,这一组地址是固定不变的,执行期不可能新增或替换之。由于程序执行时,表格的大小和内容都不会改变,所以其建构和存取皆可以有编译器完全掌握,不需要执行期任何接入。
4 执行期如何找到编译器备妥的那些虚函数的地址?
 ① 为了找到表格,每一个class object 被安插一个有编译器内部产生的指针(vptr虚函数表指针),指向表格。
 ② 为了找到函数地址,每一个虚函数被指配一个表格索引值。
    这些工作都由编译器完成,执行期要做的,只是在特定的virtual table slot(记录着virtual function的地址)中激活virtual function。
ptr->z();被转换为:
(*ptr->vptr[4])(ptr);
5 多重继承下的virtual function
    在多重继承下,虚函数复杂度围绕在第二个及后继的base classes身上,以及必须在执行期调整this指针这一点。
6 虚拟继承下的virtual function
2 指向这类成员函数的指针
①对一个虚函数,其地址在编译时期是未知的,所能知道的仅是虚函数在其相关之虚函数表中的索引值。也就是说,对一个virtual member function 取地址,所获得的只是一个索引值。
②多重继承下,指向member function的指针
    为了让指向member function的指针也能支持多重继承和虚拟继承,专家设计了下面一个结构体:
struct _mptr{
    int delta;//增量,多重继承下调整this指针用
    int index;//虚函数表中某个虚函数的索引值
    union{
        ptrtofunc faddr;//nonvirtual member function地址
        int v_offset;//一个virtual(或多重继承中的第二或后继的)base class的vptr的位置。
    };
};

Function 语意学的更多相关文章

  1. 第4章 Function语意学

    第4章 Function语意学 目录 第4章 Function语意学 4.1 Member的各种调用方式 Nonstatic Member Function(非静态成员函数) virtual Memb ...

  2. 《深度探索C++对象模型》笔记——Function语意学

    member的各种调用方式 C++支持三种类型的member functions:static.nonstatic和virtual. nonstatic member functions会被编译器转换 ...

  3. 【C++对象模型】第四章 Function 语意学

    1.Member的各种调用方式 1.1 Nonstatic Member Functions 实际上编译器是将member function被内化为nonmember的形式,经过下面转化步骤: 1.给 ...

  4. inside the C++ Object model总结

    一. 关于对象 1.内联函数:能够除去函数调用的开支,每一处内联函数的调用都是代码的复制.这是一种空间换取时间的做法,若函数代码量大或者有循环的情况下,不宜内联(这件事有些编译器会自动帮你做).在类中 ...

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

    转载:http://dsqiu.iteye.com/blog/1669614 第一章 关于对象 使用class封装之后的布局成本: class并没有增加成本,data members直接内含在每一个c ...

  6. 《深度探索C++对象模型》2

    第四章: function语意学 非静态成员函数: 名称的特殊处理: 静态成员函数由于缺乏this指针,因此差不多等于非成员函数: virtual table布局(单一继承): 单一继承下函数调用: ...

  7. [转]《深度探索C++对象模型》读书笔记[二]

    3.3 Data Member的存取1.   不管什么情况,每一个static data member只有一个实体,放在程序的data segment之中,每次程序取用static member,不管 ...

  8. 深入探索C++对象模型(四)

    Function语意学(The Semantics of Function) static member functions不可能做到的两点:(1)直接存取nonstatic数据,(2)被声明为con ...

  9. C++对象模型复习

    本文写于2017-02-24,从老账号迁移到本账号,原文地址:https://i.cnblogs.com/EditPosts.aspx?postid=6440685 一:对象模型 C++面向对象的实现 ...

随机推荐

  1. 给你讲个笑话,我是创业公司CEO

      文/办公室奇葩说(Office 78)一个在办公室较为正经的八卦号. 前几天你看见朋友圈刷屏的文章<给你讲个笑话:我是做互联网的>. 你心想,写文章的那人是傻逼吗?觉得做互联网就是个笑 ...

  2. TCP 协议

    == 已经了解了以太网和IP了,下面我们进入传输层,开始讲解TCP协议. == 仍然先把TCP报文段的格式放在这里,然后我们看图说话: TCP报文段也分为首部和数据两部分,首部默认情况下一般是20字节 ...

  3. 【转】android如何查看cpu的占用率和内存泄漏

    原文网址:http://www.cnblogs.com/yejiurui/p/3472765.html 在分析内存优化的过程中,其中一个最重要的是我们如何查看cpu的占用率和内存的占用率呢,这在一定程 ...

  4. 【转】VirtualBox direct access to SD Card in Windows--不错

    原文网址:http://www.sandyscott.net/2013/08/14/virtualbox-direct-drive-access/ I’ve trying to get my Rasp ...

  5. 高性能Java解析器实现过程详解

    如果你没有指定数据或语言标准的或开源的Java解析器, 可能经常要用Java实现你自己的数据或语言解析器.或者,可能有很多解析器可选,但是要么太慢,要么太耗内存,或者没有你需要的特定功能.或者开源解析 ...

  6. 简易封装一个带有占位文字的TextView

    在实际iOS应用开发中我们经常会用到类似于下图所示的界面,即带有占位文字的文本框:

  7. INTELLIJ IDEA集成CHECKSTYLE(转)

    转自:http://www.cnblogs.com/kiwi-wang/p/4166410.html 本文中使用intelliJ IDEA版本为14.0.1,其他版本差异不大,可同样安装. 下载安装C ...

  8. MySQL日期函数

    1.已知出生日期,求年龄 SELECT '1992-04-10' as birthday, curdate(), ( YEAR (curdate()) - YEAR ('1992-04-10')-1 ...

  9. Lesson2.1:LinkedList、ConcurrentLinkedQueue、LinkedBlockingQueue对比分析

    写这篇文章源于我经历过的一次生产事故,在某家公司的时候,有个服务会收集业务系统的日志,此服务的开发人员在给业务系统的sdk中就因为使用了LinkedList,又没有做并发控制,就造成了此服务经常不能正 ...

  10. Mysql数据库的mysql Schema 究竟有哪些东西&amp; 手工注入的基础要领

    #查看数据库版本号 mysql> select @@version; +------------+ | @@version  | +------------+ | 5.5.16-log | +- ...