c++为什么要让struct可以定义成员函数

2020-10-22 科技 141阅读
因为C++的class真的只是个struct,只不过C++编译器会在编译期对它做一些“魔改”动作而已。
早年,诸如游戏业的精灵抽象、unix系的“一切皆文件”等设计思想,都是用C乃至汇编表现出来的。正是这些思想启发并引导了后来的面向对象热潮。
对C来说,struct可以放任何它支持的数据类型。包括函数指针——后来C++所谓的虚函数表,很多编译器的实现,就是一个指向另一个全局结构体的指针,这个全局结构体里面是一条一条的函数指针,指向对应类重载后的所谓“虚函数”。
至于各种所谓的成员函数,实际上就是些第一个参数是classXX类型的this指针的普通函数。
换言之,struct本身已经足以支持面向对象编程运行期需要的一切了;现在,我们只需要增加一些新的语法约定,使得编译器可以帮助用户自动维护这些琐碎细节就行了——这正是 Bjarne Stroustrup当年搞Cfront的设计思路: 先把C++代码自动魔改到C,然后调用C编译器完成编译。
后期虽然有了直接支持c++的编译器(因为在cfront中加入异常支持失败),但编译器关于struct的处理并没有本质的不同。
于是,所谓class,其实就是加了某些外部支持的struct——除了编译期可能会被编译器魔改的面目全非外,它和普通struct毫无差别。
这个支持一般来说应该是这样的(但并不禁止编译器厂商选择其他方案):
1、对普通成员函数,为它自动添加this参数,并在调用它时,自动把 obj.method() 转换成 method(obj)格式;并识别出函数中涉及的、没有显式使用this的成员变量、为它加上this。
除此之外,别的什么都不用做。
2、对虚函数,需要为继承链上的每个类产生一个全局结构体,在这个结构体里按次序安排指向该类所有虚函数的指针,这就是虚函数表;然后在类里添加一个指向属于自己的虚函数表的指针。
那么,当用户调用某个对象的第N个虚函数时,到虚函数表查找并获取第N个函数指针指向的内容;然后类似调用普通成员函数一样,把 obj.method() 转换成 method(obj)格式,多态就实现了。
当然,除此之外,还要在编译时执行权限检查,避免非法访问类的protect/private成员(struct默认权限是public,class是private);以及另外一些琐碎工作。
所以你看,c++的类归根结底,它就是个C语言的struct。只是(相当于)在编译期做了些预处理而已——只要你在里面声明了成员函数,就会自动触发预处理,从而实现“自动魔改你所定义的数据结构,使其支持OO诸要素”功能。
那么,除了让C代码共用C++里面定义的struct这个特殊场景外(想了解这类能兼容C的数据类型,可搜索 POD类型),你说还有什么理由禁止struct拥有成员函数呢?
望采纳,谢谢
声明:你问我答网所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系fangmu6661024@163.com