聚C语言回家过春节,认识了很多小伙伴:Java、Python、JavaScript、Ruby……大家都在大城市发展的不错,回到家,聚餐,聊天,喜气洋洋。尤其是Python和JavaScript成为了明星。一个吹嘘他是人工智能的一绝,一个吹嘘他是世界上最流行的语言。我不相信有某个语言流行度榜单作为证据,而且GitHub上有那么多项目。老练的Java一直在谈TIOBE排行榜:“我连续10多年排名第一,高度让人望而却步!”说起TIOBE,Python更是得意洋洋:“我今年还被选为TIOBE的领军人物,年度编程语言!”虽然在TIOBE常年排名第二,但C语言有点郁闷。人写的程序有不少,但都在最底层。系统级编程,什么操作系统,数据库,编译器。...与应用层相比,它并没有那么光鲜亮丽。现在很多人都学过Python,Java说会编程。不懂指针,不懂内存,不懂底层的基本原理,那还算是编程吗?这种压抑是在美食上发泄的。举杯敬酒之间,Java搂住了C的肩膀,亲切地说:“哥,你有约会吗?”现在是马蜂窝,大家的目光都集中在了C语言上。C喃喃了半天:“不……不。”“哈哈哈……我们都有约了,你都这么大了还有约?!”蟒蛇笑了。“是的,没有对象的编程语言的未来是什么?”JavaScript做出了决定。他之前没有类的概念,但是OOP是通过“原型”来实现的。class关键字是近几年才在语法层面引入的。“虽然我没有对象,但我有指针,非常强大。”“指针?你说的是容易出错的指针吗?现在谁用指针?”JavaScript说。“如果你不知道如何使用指针,你就不是真正的程序员!”C语言脸红了。饭桌上的气氛变得有些尴尬,刺筐的爪哇招呼道:“走吧,我们继续喝酒。”好不容易熬过晚宴,C语言又回到了我家。家里空无一人,我的“爸爸”DennisRitchie,有史以来最伟大的程序员之一,于2011年10月去世了。不幸的是,桌上有一本书《C程序设计语言》,是DennisRich唯一的遗作。C拿起这本书,不禁心酸。访问C语言时,他突然想起了KenThompson,当时他在对门就是丹尼斯·里奇的“好朋友”,他们两人共同创造了伟大的Unix操作系统,并获得了计算机界的最高奖项:图灵奖。你让我搭档?不让我面向对象编程!C语言来到KenThompson家门口,按响门铃,门开了。C语言看到KenThompson玩Go玩得开心,心里更惨了。Go是他的亲人。儿子,我是谁,转身就要走,肯却在背后叫住了他:“李小C,进来和你哥一起去玩一会儿吧。看到C一脸垂头丧气的样子,肯也很意外:“都过年了,怎么回事?”C不满道:“你当年怎么不让我约会?”让我们谈谈面向对象的编程吧!其实你自己的父亲设计你,主要是为了系统级的编程。你要的是贴近硬件,你要的是效率。你为什么要那么复杂的东西?现在,你和Go一样,你没有结构吗?”肯转向围棋,眨了眨眼睛。“是啊,结构非常有用!”马上附和。“但是struct无法实现OOP,Python,JavaScript他们都笑话我了!”“那你告诉我,什么是OOP?”Ken问道。“嗯,就是封装,继承,多态?”C回答。下面我来给大家分解一下,C语言是如何实现封装、继承和多态的!这个封装就是把信息隐藏起来,大家先看这段代码。”这里的shape.hshape.cmain.c定义了一个名为Shape的结构体,外界只能通过相关函数对这个Shape进行操作,比如创建(Shape_create)、移动(Shape_move)、获取位置(Shape_getX)等,不能直接访问Shape内部的数据结构,虽然没有class这个关键字,但是数据结构和相关操作都是单独写的,看起来不完美,但是确实实现了封装。C看了KenThompson其实把那个指针的名字叫做self,和Python的一样,不禁笑了:“原来如此,继承呢?”继承人KenThompson二话不说继续写代码,大牛的风格好像也差不多:别瞎BB,showmethecode。这次定义了一个矩形(Rectangle)结构,Shape嵌套在里面.这是实现继承了吗?C有点懵,旁边的围棋小子喊道:“我知道了,记忆中他们是这样的。”》通过这种组合方式,也算是继承的实现,多态可以如此轻松的实现封装和继承,C语言很精彩,但是如何实现多态呢?这时候,敲门声又来了,大神Linus他端着一瓶酒进来,想和C的那家伙喝酒,看到桌上的代码,顿时明白是怎么回事了,他说:“别搞那么多花里胡哨的东西,就是多态,不就是一个函数指针嘛!让我举一个例子。”“这个结构体包含两个函数指针,一个用来计算图形的面积,一个用来画图形。我们称这个结构为虚函数表。”“这个有什么用?”“在你的Shape中,添加一个指向函数表的指针就可以了。林纳斯回答。C和Go看起来都是一片空白。“白痴,你想想,当你创建一个子类对象,比如Rectangle,把那个虚函数指针vptr指向另一组函数,会发生什么?”两人还是不明白,Linus只好继续画:现在C有点明白了。无论是Rectangle对象还是Square对象,在调用Shape_area方法时,都需要通过vptr指针在虚函数表中找到area方法。对于矩形,您可以找到Rectangel_area方法。对于Square,您会发现Square_area方法。structRectangle*r=Rectangle_create(5,5,10,10);Shape_area((structShape*)r);“其实和你哥C++的多态实现原理差不多!在运行时找到真正的函数去执行,”Ken总结道。“是的,这种使用函数指针的方法太常见了,在我的Linux操作系统中也会定义类似的东西,”Linus说,“只要IO设备提供了这些函数的实际定义,File结构就可以了如果body的函数指针指向对应的实现,那么就可以用同一套接口来操作不同的IO设备。C语言开心:“哈哈,我说我的指针很厉害,这些都是通过指针实现的”“是啊,别听Java,Python,JavaScript,都是瞎BB,你也有对象,还有你也可以进行面向对象的编程!”C语言说:“走,喝!”注:本文的例子主要来自https://www.state-machine.com/doc/AN_OOP_in_C.pdf我做了修改。【本文为专栏作家“刘欣”原创稿件,转载请通过作者微信获取授权公众号编码】点此查看该作者更多好文
