C++ Member Functions的各种调用方式

【1】Nonstatic Member Functions(非静态成员函数)

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

float magnitude3d(const Point3d* _this) {...};
float Point3d::magnitude3d() const {...};

那么选择member function不应该带来什么额外负担。这是因为编译内部已将“member 函数实体”转换为对等的“nonmember函数实体”。

下面就是转化步骤:

1、改写函数的signature以安插一个额外的参数到member function中,用以提供一个存取管道,是class object得以调用该函数。该额外参数被称为this指针;

2、将每一个“对nonstatic data member的存取操作”改为经由this指针来存取;

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

现在这个函数已经被转换好了,而其每一个调用操作也都必须转换。于是:

obj.magnitude();

变成了:

magnitude_7Point3dFv(&obj);

ptr->magnitude();

变成了:

magnitude_7Point3dFv(ptr);

【2】Static Member Functions(静态成员函数)

如果Point3d::normalize()是一个static member function,以下两个调用操作:

obj.normalize();

ptr->normalize();

将被转换为一般的nonmember函数调用,像这样:

normalize_7Point3dSFv();        //obj.normalize();
normalize_7Point3dSFv();        //ptr->normalize();

【3】Virtual Member Functions(虚拟成员函数)

如果normalize()是一个virtual member function,那么以下的调用:

ptr->normalize();

将会被内部转化为:

(*ptr->vptr[1])(ptr);

其中:

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

(2)1是virtual table slot的索引值,关联到normalize()函数。

(3)第二个ptr表示this指针。

时间: 2024-11-10 01:12:19

C++ Member Functions的各种调用方式的相关文章

C++对象模型——Member的各种调用方式(第四章)

第四章 Function语意学 (The Semantics of Function) 如果有一个Point3d的指针和对象: Point3d obj; Point3d *ptr = &obj; 当这样做: obj.normalize(); ptr->normalize(); 时,会发生什么事情呢?其中的Point3d::normalize()定义如下: Point3d Point3d::normalize() const { register float mag = magnitude()

函数的效能 & 指向 Member Functions 的指针与其效能

nonmember friend 或 nonstatic member 或 static member 函数都会被转化为相同的形式, 因此三者的效率完全相同.另外, inline member function 的效率一直是最高的(前提是简单操作), 优化后的效率更是高, 这是因为编译器会将被视为不变的表达式提到循环之外, 因此只计算一次, inline 函数不只能够节省一般函数所调用的负担, 也提供程序额外的优化机会.virtual function 和 多重继承 的效率要低于一般函数, 要再

Virtual Member Functions & Static Member Function

如果一个 normalize() 是一个 virtual member function, 那么以下的调用: ptr->normalize(); 将会被内部转化为: (*ptr->vptr[1])(ptr); 其中:vptr 表示由编译器生成的指针, 指向 virtual table, 它被安插在每一个声明有(或继承自) virtual functinos 的 class object 中. 事实上其名称也会被 mangled, 因为在一个复杂的 class 派生体系中, 可能存在多个 vpt

C++对象模型——Virtual Member Functions (虚拟成员函数)(第四章)

4.2 Virtual Member Functions (虚拟成员函数) 已经看过了 virtual function的一般实现模型:每一个 class 有一个 virtual table,内含该 class 中有作用的 virtual function的地址,然后每个object有一个vptr,指向 virtual table的所在. 为了支持 virtual function机制,必须首先能够对多态对象有某种形式的"执行期类型判断法(runtime type resolution)&quo

C++ static member functions

今天复习老师昨天讲的static member functions.总觉得这玩意儿存在真是莫名其妙,度娘之,发现网上讲的都十分不清楚.还是用Google从米国网站找到了答案. class Something { private: static int s_nValue; }; int Something::s_nValue = 1; // initializer int main() { // how do we access Something::s_nValue? } In this cas

线程安全的事件调用方式

通常事件调用方式为 //版本1 public event NewEventHandler NewEvent;protected virtual void OnNewEvent(EventArgs e){ if (NewEvent != null) NewEvent(this, e);} 但这种方式的问题在于,在做NewEvent != null 检测之后,NewEvent事件调用之前,事件取消了注册,即NewEvent重新变成null,此时再进行调用,将会抛出异常 线程安全的做法, //版本2

《C++反编译与逆向分析技术揭秘》之学习笔记03--函数的调用方式

※函数的调用方式 EBP:扩展基址指针寄存器(extended base pointer) 其内存放一个指针,该指针指向系统栈最上面一个栈帧的底部. ESP:(Extended stack pointer)是指针寄存器的一种,用于指向栈的栈顶. _cdecl:C/C++默认的调用方式,调用方平衡栈,不定参数的函数可以试用. 调用方:1.参数压栈.esp-=42.调用函数.3.实现栈平衡.esp+=4 此处的printf也是同样道理0x004010CB.0x004010CC两处压入参数,共8个字节

js实现类似于add(1)(2)(3)调用方式的方法

群里有人说实现类似add(1)(2)(3)调用方式的方法,结果马上有人回答: var add = function(a){ return function(b){ return function(c){ return a+b+c; }; }; }; add(1)(2)(3); //6 没错!那要是add(1)(2)(3)(4) 这样4个调用呢,那这个肯定不适用了. 这种就是类似于执行一个函数返回函数自身值: function add(x) { var sum = x; var tmp = fun

简述自己用过的几种异步调用方式

直接上代码 1.BeginInvoke和EndInvoke方式 private static void BeginInvoke1() { Func<int,string> fun = Todo; for (int i = 0; i < 5; i++) { //fun.BeginInvoke(i,TodoCallBack, fun); /* 异步调用委托BeginInvoke * handler.EndInvoke(x)为执行委托的结果 */ fun.BeginInvoke(i, x =&