[读书笔记] 深入探索C++对象模型-第四章-Function语义学(上)
2016-09-10 21:43
309 查看
开始整理第四章的内容,关于函数的东西。
1. 静态成员函数不可以是const的,原因是因为this指针,详细参考:http://blog.csdn.net/beyongwang/article/details/52403697
2. 成员函数可以分成几类:
a. 非静态成员函数:此类函数会隐含一个this指针传入函数体,举个例子,对于如下函数:
调用步骤如下:改写函数签名,添加this指针,对于const函数,会添加const A* this:
会转化成:
b. 虚拟成员函数:严格来说,虚函数也属于非静态成员函数,二者拥有部分相同的处理,但是由于跟普通的非静态成员函数处理上又有所不同,所以单独分成一类。例如,如果对于类A的一个虚成员函数v_Fun(void),这个调用pa->v_Fun(),可能会被转成为(* pa->vptr[1])(pa);其中,
i. vptr是编译器产生的指向虚表的指针,对于所有含有或者继承有虚函数的类,都会存在,其名字可能也会被mangling化,因为同一个类中可能存在 多个此类指针。
ii. 1是虚表槽的索引值,说明此函数位于虚表第二个函数槽中。
iii. 第二个pa表示this指针。
注意,使用类对象调用虚函数和调用非虚函数的处理是一样的,并不会涉及虚表,例如:a.v_Fun()会转化为:v_Fun_7AFv(&a),跟上面调用非静态成员函数是一样的。这是因为类对象的类型是确定的,所以不必通过虚函数机制来决定被调用函数的地址。
c. 静态成员函数:
静态成员函数跟非静态成员函数的区别在于,前者没有this指针,因为从所属关系上来看,前者属于整个类,不存储特定的类实例状态,而后者可能因为不同的实例而产生不同的结果。例如,对于类A的一个静态成员函数void static_Fun(void),这个调用pa->static_Fun();以及这个调用:a.static_Fun();都会转化为一般的非成员函数调用:static_Fun_7ASFv();
几个静态函数的特征:
i. 它不能直接存取所属类的非静态数据成员。
ii. 它不能被声明为const, volatile或者virtual。
iii. 它不需要通过类实例对象调用,A::static_Fun()。
取静态成员函数的地址: &A::static_Fun(),得到的是其在内存中的位置,也就是一个普通的函数指针:void (*)(),而不是指向类成员函数的指针void (A::*)()(关于指向类成员函数的指针,跟指向类成员变量的指针有点类似,之后会有整理)。
1. 静态成员函数不可以是const的,原因是因为this指针,详细参考:http://blog.csdn.net/beyongwang/article/details/52403697
2. 成员函数可以分成几类:
a. 非静态成员函数:此类函数会隐含一个this指针传入函数体,举个例子,对于如下函数:
float A::non_Static_Fun(){ return m_a * m_a; }
调用步骤如下:改写函数签名,添加this指针,对于const函数,会添加const A* this:
float A::non_Static_Fun(A* this){ ... }将每一个非静态数据成员的存取改为由this指针来做:
float A::non_Static_Fun(A* this){ return this->m_a * this->m_a; }将成员函数重新写成一个外部函数,对函数名字进行mangling处理,一般的处理方法是函数名称+参数数目+加参数类型,注意没有返回值,这也是为什么C++中,函数重载不允许通过返回值来区分,(添加extern C关键字可以阻止这种mangling),使其成为独一无二函数名字:
extern non_Static_Fun_7AFv(...);相应的对于这个函数的调用操作也会被转换:
a.non_Static_Fun();会转化为
non_Static_Fun_7AFv(&a);指针调用:
pa->non_Static_Fun();
会转化成:
non_Static_Fun_7AFv(pa);
b. 虚拟成员函数:严格来说,虚函数也属于非静态成员函数,二者拥有部分相同的处理,但是由于跟普通的非静态成员函数处理上又有所不同,所以单独分成一类。例如,如果对于类A的一个虚成员函数v_Fun(void),这个调用pa->v_Fun(),可能会被转成为(* pa->vptr[1])(pa);其中,
i. vptr是编译器产生的指向虚表的指针,对于所有含有或者继承有虚函数的类,都会存在,其名字可能也会被mangling化,因为同一个类中可能存在 多个此类指针。
ii. 1是虚表槽的索引值,说明此函数位于虚表第二个函数槽中。
iii. 第二个pa表示this指针。
注意,使用类对象调用虚函数和调用非虚函数的处理是一样的,并不会涉及虚表,例如:a.v_Fun()会转化为:v_Fun_7AFv(&a),跟上面调用非静态成员函数是一样的。这是因为类对象的类型是确定的,所以不必通过虚函数机制来决定被调用函数的地址。
c. 静态成员函数:
静态成员函数跟非静态成员函数的区别在于,前者没有this指针,因为从所属关系上来看,前者属于整个类,不存储特定的类实例状态,而后者可能因为不同的实例而产生不同的结果。例如,对于类A的一个静态成员函数void static_Fun(void),这个调用pa->static_Fun();以及这个调用:a.static_Fun();都会转化为一般的非成员函数调用:static_Fun_7ASFv();
几个静态函数的特征:
i. 它不能直接存取所属类的非静态数据成员。
ii. 它不能被声明为const, volatile或者virtual。
iii. 它不需要通过类实例对象调用,A::static_Fun()。
取静态成员函数的地址: &A::static_Fun(),得到的是其在内存中的位置,也就是一个普通的函数指针:void (*)(),而不是指向类成员函数的指针void (A::*)()(关于指向类成员函数的指针,跟指向类成员变量的指针有点类似,之后会有整理)。
相关文章推荐
- [读书笔记] 深入探索C++对象模型-第四章-Function语义学(下)
- [读书笔记] 深入探索C++对象模型-第四章-Function语义学(下续)
- [读书笔记] 深入探索C++对象模型-第四章-Function语义学(中)
- [读书笔记] 深入探索C++对象模型-第四章-Function语义学(中续)
- [读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(中)
- [读书笔记] 深入探索C++对象模型-第三章 Data语义学(下)
- 深入探索C++对象模型 读书笔记
- [读书笔记] 深入探索C++对象模型-第七章-站在对象模型的尖端(中)
- 深入探索C++对象模型 读书笔记
- [读书笔记] 深入探索C++对象模型-第六章-执行期语义学(下)
- [读书笔记] 深入探索C++对象模型-第五章-构造、析构、拷贝语义学(中)
- 深入探索C++对象模型 读书笔记
- [读书笔记] 深入探索C++对象模型-第一章《关于对象》
- 深入探索C++对象模型:第四章 Function语意学
- [读书笔记] 深入探索C++对象模型-第五章-构造、析构、拷贝语义学(上)
- [读书笔记] 深入探索C++对象模型-第二章《构造函数语义学》(上)
- [读书笔记] 深入探索C++对象模型-第五章-构造、析构、拷贝语义学(下)
- [读书笔记] 深入探索C++对象模型-第七章-站在对象模型的尖端(下)
- C++ 零散知识点速记 -- <深入探索C++对象模型> 读书笔记
- [读书笔记] 深入探索C++对象模型-第三章 Data语义学(中)