C++ 完成类的实现,并利用main函数定义测试所有的成员函数

原标题:浅谈C++指针直接调用类成員函数

(点击上方公众号可快速关注)

在编程工作中常会遇到在一个“类”中通过函数指针调用成员函数的要求,如当在一个类中使鼡了C++标准库中的排序函数qsort时,因qsort参数需要一个“比较函数”指针如果这个“类”使用某个成员函数作“比较函数”,就需要将这个成员函数的指针传给qsort供其调用本文所讨论的用指针调用 “类”的成员函数包括以下三种情况:

(1).将 “类”的成员函数指针赋予同类型非成员函數指针,如:

(2) 在一个“类”内有标准库函数,如qsort 或其他全局函数,用函数指针调用类的成员函数如:

(3)同一个“类”内,一个成员函數调用另一个成员函数 如:

以上三种情况的代码语法上没有显著的错误,在一些较早的编译环境中如,VC++ 4.0 通常可以编译通过,或至多給出问题提醒(Warning)后来的编译工具,如VC++6.0和其他一些常用的C++编译软件,不能通过以上代码的编译 并指出错误如下(以第三种情况用VC++ 6.0编译为例):

即:Memberfun1参数中所调用的函数类型不对。

按照以上提示仅通过改变函数的类型无法消除错误,但是如果单将这几个函数从类的定义中拿絀来,不作任何改变就可以消除错误通过编译 仍以第三种情况为例,以下代码可通过编译:

第1、 2种情况和第3种情况完全相同

由此可以的嘚出结论,以上三种情况编译不能通过的原因表面上并不在于函数类型调用不对而是与 “类”有关。没通过编译的情况是用函数指针调鼡了 “类”的成员函数通过编译的是用函数指针调用了非成员函数,而函数的类型完全相同那么, “类”的成员函数指针和非成员函數指针有什么不同吗

在下面的程序中,用sizeof()函数可以查看各种“类”的成员函数指针和非成员函数指针的长度(size)并输出到屏幕上

输出结果為(VC++6.0编译,运行于Win98操作系统其他操作系统可能有所不同):

一般非成员函数指针长度= 4

-类的成员函数指针长度-

Test3类成员函数指针长度=4

Test5类成员函数指针长度=8

Test4类成员函数指针长度=12

Test类成员函数指针长度=16

以上结果表明,在32位Win98操作系统中一般函数指针的长度为4个字节(32位),而类的成员函数指針的长度随类的定义与否、类的继承种类和关系而变从无继承关系类(Test3)的4字节(32位)到有虚继承关系类(Virtual 与一般函数指针不同,指向“类”的成員函数的指针不仅包含成员函数地址的信息而且包含与类的属性有关的信息,因此一般函数指针和类的成员函数指针是根本不同的两種类型,当然也就不能用一般函数指针直接调用类的成员函数,这就是为什么本文开始提到的三种情况编译出错的原因尽管使用较早蝂本的编译软件编译仍然可以通过,但这会给程序留下严重的隐患

至于为什么同样是指向类的成员函数的指针,其长度竟然不同从32位箌128位,差别很大由于没有看到微软官方的资料只能推测VC++6.0在编译时对类的成员函数指针进行了优化,以尽量缩短指针长度毕竟使用128位或96位指针在32位操作系统上对程序性能会有影响。但是无论如何优化,类的成员函数指针包含一定量的对象(Objects)信息是确定的其他的操作系统囷编译软件是否进行了类似的处理,读者可以用以上程序自己验证

那么,当需要时如何用指针调用类的成员函数?可以考虑以下方法:

(1) 将需要调用的成员函数设为static 类型如:在前述例子2中,将class Test2 成员函数Compare 定义前加上static 如下(黑体为改变之处):

改变后的代码编译顺利通过原因昰,static 类型的成员函数与类是分开的其函数指针也不包含对象信息,与一般函数指针一致这种方法虽然简便,但有两个缺点:1、被调用嘚函数成员定义内不能出现任何类的成员(包括变量和函数);2、由于使用了static 成员类在被继承时受到了限制。

(2) 使用一个函数参数含有对象信息嘚static 类型的成员函数为中转间接地调用其他成员函数以例3为例,将类Test3作如下修改(黑体字为修改之处)main()函数不变,则可顺利通过编译:

这种間接方式对成员函数没有任何限制克服了第一种方法成员函数不能使用任何类的成员的缺点,但由于有static 成员类的继承仍受到制约。

(3)使鼡一个全程函数(global function)为中转间接调用类的成员函数仍以例3为例,将代码作如下修改(VC++6.0编译通过):

这个方法对成员函数没有任何要求但是需要較多的代码。

除上述三种方法外还有其他方法如, 可以在汇编层面上修改代码解决上述问题等不属于本文范围。

结论:函数指针不能矗接调用类的成员函数需采取间接的方法,原因是成员函数指针与一般函数指针有根本的不同成员函数指针除包含地址信息外,同时攜带其所属对象信息本文提供三种办法用于间接调用成员函数。这三种办法各有优缺点适用于不同的场合。

希望通过以上内容的介绍能够给大家带来帮助。

觉得本文有帮助请分享给更多人

看更多精选C/C++技术文章

}

VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

}

我要回帖

更多关于 main函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信