C++对象模型(五)

第四章函数语义学


众所周知的,在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、    不能声明为constvolatilevirtrual
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 指向的是该类的虚函数表。类的虚函数表中包含了类中所有的虚函数( 即使有纯虚函数,也被包含在内,虽然基本上是不可能有调用的) 。如果该类中没有虚函数,但是所继承的基类中有同名虚函数,那么该虚函数也会被放到类的虚函数表中。也就是说对于类PointPoint2D 的对象,都有一个自己的虚函数表。并且类中有vptr 指向这个表。
所以对于Ptr->Point() ,编译器先通过Ptr 找到该类对象的vptr ,根据函数名字又可以得到函数在虚函数表中的索引,进而找到该函数的执行代码。如果Point() 在虚函数表中的索引为2 ,则这个表达式可以写为:
       (*Ptr->vptr[2])(Ptr);
       这样,只需要在执行期知道Ptr的类型,就可以调用合适的函数处理了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值