现在的位置: 首页 > 综合 > 正文

C++对象模型(五)

2019年03月13日 ⁄ 综合 ⁄ 共 1359字 ⁄ 字号 评论关闭

第四章函数语义学

众所周知的,在C++
中,跟类相关的成员函数有三种,静态函数、非静态函数、虚拟函数。本章介绍了这几种函数的来源、用在何处、编译器如何实现、及效率。


非静态成员函数:

简单的说,非静态成员函数就是非成员函数中加入了一个this
指针的参数(不需要其他更多的解释了)。


书中还特意提到了名称的特殊处理(Name Mangling
)。


一般来说,对于一个非静态成员函数,Name Mangling
的处理后的函数名是:函数名+类名+参数名。加类名是为了区分多重继承的相同名字的成员函数;而加参数名,则是区分函数重载。作者还特意提到返回值并不加入name mangling


如果仅仅是返回值不同的两个成员函数,VC
编译器会报错:


error
C2556: 'float __thiscall namemangling::x(void)' : overloaded function
differs only by return type from 'void __thiscall namemangling::x(void)'


静态成员函数:

这里没有什么内容。作者着重介绍了静态成员函数的来源。静态成员函数的主要特征在于:没有this
指针,由这个主要特征,衍生出以下主要特征:


1、
  

不能直接存取类中的非静态成员;

2、
  

不能声明为const
volatile
virtrual


3、
  

不需要经由类对象调用;(抄书)

虚拟成员函数:

说到虚拟成员函数,就必须谈到多态。虚拟函数的产生就是为了满足多态的需要(我是这么理解的)。要把这个道理说清楚还真不容易,作者花了整整六页,画了很多图表,举了很多例子试图将虚拟继承将清楚。这里我也尝试一下,以更短的语言将最简单虚拟继承和多态将清楚。

先举个最简单的例子:

有一个基类,

Class Point

{

       Public:


       Virtual ~Point();


       Virtual Point& mult() = 0;


       Protected:


       Float _x


};

Class Point2D : public Point

{

       Public:


       ~Point();


       Point2D& mult();


};

对于这个最简单的虚拟继承链,假设有一个表达式为:

Ptr->Point();

那么,这个函数到底是指向哪个类的函数呢?C++
又是如何实现的?本段就是解决这个问题。


C++
中,对于每一个存在虚函数的类中,都会添加一个指针vptr
。该vptr
指向的是该类的虚函数表。类的虚函数表中包含了类中所有的虚函数(
即使有纯虚函数,也被包含在内,虽然基本上是不可能有调用的)
。如果该类中没有虚函数,但是所继承的基类中有同名虚函数,那么该虚函数也会被放到类的虚函数表中。也就是说对于类Point
Point2D
的对象,都有一个自己的虚函数表。并且类中有vptr
指向这个表。


所以对于Ptr->Point()
,编译器先通过Ptr
找到该类对象的vptr
,根据函数名字又可以得到函数在虚函数表中的索引,进而找到该函数的执行代码。如果Point()
在虚函数表中的索引为2
,则这个表达式可以写为:


       (*Ptr->vptr[2])(Ptr);


       这样,只需要在执行期知道Ptr的类型,就可以调用合适的函数处理了。

抱歉!评论已关闭.