之前我们讲过编译器会对 nonmember functions 进行怎样的扩充和该写,今天我们来讲一下 member functions 函数调用方式

一、Nonstatic Member Functions(非静态成员函数)

  C++的设计准则之一就是:nonstatic member function 至少必须和 nonmember function 有相同的效率。也就是说如果们要在以下两个函数之间选择:

    float member_fun( const classA *_this){...};

    float classA::member_fun() const{...};

  那么选择 member function 不应该带来什么额外负担,因为编译器内部已经将“member 函数实体”转换为对等的“nonmember函数实体”,假设 member_fun()函数是这样:

  float member_fun( const classA *_this){ return sqrt(_this->x*_this->x+_this->y*_this->y+_this->z*_this->z);} ,咋看这个函数大家可能觉得没什么效率,因为它不能直接对 class 的成员进行操作。而 member functions 却可以。然而,member functions 要经过如下步骤转化为 nonmember function

  1.改写函数原型以安插一个额外的参数到 member function 中,用以提供一个存取管道,使class object 得意调用该函数,该额外参数被成为 this 指针。

  float classA::member_fun() const;被转化为 float ClassA::member_fun(const classA *const this);non-const member function 会转化为 float ClassA::member_fun(classA *const this);

  2.将每一个对 class nonstatic data member 的存取操作,改为经由 this 指针来存取:

    {

      return sqrt(

            this->x*this->x+

            this->y*this->y+

            this->z*this->z

            )

    }

  3.将 member function 重新写成一个外部函数,对函数名称进行 mangling 处理,使它在程序中成为独一无二的词汇。

     函数转化好以后,所有的调用操作都要转换:classa.member_fun(); 会被转化为(假设这里的member_fun 被 mangling 为 member_fun_classAFv) member_fun_classAFV( &classa );

  

  这样,一个 nonstatic member function 就被转化为 一个 member function 了,其他的函数体内优化都会类似于之前讲的普通函数优化相同了!

二、Virtual Member Function(虚拟成员函数)      

  我们知道如果一个 virtual member function 是通过 class object 调用是没有多态性的,会当做一般的 nonstatic member function 函数进行处理。只有通过指针或者引用才有多态性。那么多态如何实现呢?

    ptr->virtual_member_fun();

  会被内部转化为 (*ptr->vptr[1])( ptr );

  1. vptr 表示编译器产生的指针,指向 virtual table ,他被安插在每一个“声明有(或继承自)一个或多个 virtual function” 的 class object 中。事实上其名称会被 mangled,因为在一个复杂的 class 派生类体系中有可能存在有多个 vptrs。

  2.1 是 virtual table slot 的索引值。关联到 virtual_member_fun() 函数。

  3.第二个 ptr 是 this 指针---同一般的nonstatic member function。

三、Static member functions(静态成员函数)

  静态成员函数由于是独立于 class 的,在调用时不能再像以上两种函数那样安插一个 this 指针。这样,static member functiongs 就有了如下特性:

  1.它不能直接存取其 class 中的 nonstatic members。

  2.他不能够被声明为 const、volatile 或者 virtual。

  3.它不需要经由 class object 才被调用---虽然大部分时候他是这样被调用的!

  一个 static member function 会被提到 class 声明之外,并进行 mangled 处理,这样就可以与其他的静态成员变量区别开来(所有的静态成员都是放在一个静态内存内)。

Function语义学之member function的更多相关文章

  1. Thinkphp---------Call to a member function free_result() on a non-object

    1.平时用框架用久了,直接执行原生的sql反而做起来反应迟钝了.今天遇到一个问题,就是直接执行一个添加的sql语句,然后我用了TP框架的M()->query();方法.运行以后,会报Call t ...

  2. :( Call to a member function Table() on a non-object 错误位置

    :( Call to a member function Table() on a non-object 错误位置 $Model不是模板,是你自己先前链接数据库返回的对象...我的是改为$Form

  3. Fatal error: Call to a member function bind_param() on a non-object in

    今天在练习 mysql是出现错误:   Fatal error: Call to a member function bind_param() on a non-object in 解决步骤: 1. ...

  4. ECmall错误:Call to a member function get_users_count() on a non-object

    问题描述: 在后台添加了一个app报错:Call to a member function get_users_count()Fatal error: Call to a member functio ...

  5. magento后台 Fatal error: Call to a member function getId() on a non-object in错误

    后台分类管理出现错误 Fatal error: Call to a member function getId() on a non-object in 在数据库中运行以下sql语句 INSERT I ...

  6. Timer.4 - Using a member function as a handler

    In this tutorial we will see how to use a class member function as a callback handler. The program s ...

  7. C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化

    模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...

  8. About The Order of The Declarations And Definition When Making a Member Function a Friend.关于使类成员成为另一个类友元函数的声明顺序和定义。

    If only member function clear of WindowMgr is a friend of Screen, there are some points need to note ...

  9. About Why Inline Member Function Should Defined in The Header File

    About why inline member function should defined in the header file. It is legal to specify inline on ...

随机推荐

  1. Java语言基础(一)

    Java语言基础(一) 在这里说明一下,有基础的跳过 高手跳过.在这里我想复习以前的东西,以及给正在学java的一些帮助 我用的MyEclipse8.5编写java代码,有需要联系我  QQ:9035 ...

  2. c#中跨线程调用windows窗体控件

    c#中跨线程调用windows窗体控件解决. 我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题.然而我们并不能用传统方法来做这个问题,下面我将详细的介绍.首先来 ...

  3. xcode升级或者重新安装后不能编译的解决方法

    昨天由于xcode有一些问题,因此进行了重新安装,结果安装好后进行编译,没有进行任何改动的代码出现了两个fatal error 查看错误信息为什么的header has allready build, ...

  4. java获取计算机硬件参数

    public class HardWareUtils { /**   *   * 获取主板序列号   *   *   *   * @return   */ public static String g ...

  5. css 权威指南笔记( 五)结构和层叠之三种样式来源

    CSS中的样式一共有三种来源:创作人员.读者和用户代理,来源的不同会影响到样式的层叠方式 首先,创作人员(author's+style)样式应该是我们最熟悉的,如果你是一个前端开发者,那么你写的那些样 ...

  6. 一次优化web项目的经历记录(一)

    一次优化web项目的经历记录 这段时间以来的总结与反思 前言:最近很长一段时间没有更新博客了,忙于一堆子项目的开发,严重拖慢了学习与思考的进程.开水倒满了需要提早放下杯子,晚了就会烫手,这段时间以来, ...

  7. html、body、document、window的区别

    html是一门超文本标记语言: document对象代表整个html文档,可用来访问页面中的所有元素: body代表document的主体子对象,除浏览器头部,页面中能够看到的内容都属于body中的内 ...

  8. float与double剖析

    今天研究下float与double的编码 float: 我们来看一下这组数是如何一步步从16进制转换到float的 float编码格式: 1.将16进制转换到2进制 整理后:0 1000 0010 1 ...

  9. Ubuntu Server 14.04 下root无法ssh登陆

    今天安装了Ubuntu Server 14.04   在终端配置了root密码后,使用SecureCRT和putty竟然不能ssh登陆,SecureCRT一直提示密码不对,但是可以肯定输入的密码100 ...

  10. method=“post/get”

    Form表单中method="post/get'的区别   Form提供了两种数据传输的方式——get和post.虽然它们都是数据的提交方式,但是在实际传输时确有很大的不同,并且可能会对数据 ...