之前我们讲过编译器会对 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. SQLLite 简介

    [1] SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内 ...

  2. Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧

    第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...

  3. Android进阶笔记03:Android应用中实现查看"附近的人"的功能

    1. 要实现" 附近的人" 这功能,然后就研究了下: (1)首先要做的就是要获取到自己当前位置的经纬度(编程获取手机GPS定位模块的信息,进而获取自己当前位置的经纬度) (2)然后 ...

  4. css考核点整理(八)-在什么情况下通过img引入图片,什么情况用背景图引入?背景属性有哪些

    在什么情况下通过img引入图片,什么情况用背景图引入?背景属性有哪些

  5. iOS UIKit:viewController之动画(5)

    当弹出一个view controller时,UIKit提供了一些标准转换动画,并且也支持用户自定义的动画效果. 1 UIView动画 UIView是自带动画实现功能,其中有两种方式实现:        ...

  6. windows 环境下mysql 如何修改root密码

    windows 环境下mysql 如何修改root密码 以windows为例: 无法开启服务,将mysql更目录下的data文件夹清空,然后调用 mysqld --initialize 开启mysql ...

  7. 关于c++中的引用

    引用是个别名. 1.引用是否占用空间 引用是否占用空间,此处是指广义上的占用内存空间,即为该对象新开辟一块内存.这个需要分不同的情况. 首先看一下常引用(const 引用). 这里关于常引用在c++  ...

  8. C#调用百度云存储接口上传文件

    因前几日见园子里有人说可以把网站静态文件放在百度上,于是去百度开放平台看了看,发现之前那篇文章不是调的云存储接口啊... 于是自己写了个C#能调百度云存储的例子(百度云开放平台只提供php.java. ...

  9. angularjs-googleMap googleMap api地址解析与反解析

    1.js:根据地址得到经纬度var myplace=$scope.place;//获取输入的地址var geocoder = new google.maps.Geocoder();//创建geocod ...

  10. java 进制.

    /* 整数的'3'种表现形式: 1,十进制. 2,八进制. 3,十六进制. */ public class IntegerDemo { public static void main(String[] ...