C语言面向对象编程
C语言面向对象编程 原创作者: rubynroll 阅读:5643次 评论:0条 更新时间:2008-12-15 经常看到关于OO编程的讨论,C+, Java, C#.还有最近很流行的动态语言Python,Ruby等,但很少看到有C的份。在我看来,OO编程的核心是OO的思想,用什么语言倒是其次。但是,不可否认,那些专门为OO编程设计的语言可以比较方便和自然地表达OO思想,有些语言甚至强制使用OO特性。 C,作为最贴近底层的高级语言,拥有简洁的语法和直接内存操作能力(指针),大量运用于系统级编程,如操作系统内核,驱动程序等。而在嵌入式系统中,由于资源有限等因素,更倾向于用C编程。 C虽然在语言特性上并没有体现OO特性,但是依然可以通过各种编程技巧来体现OO的思想。由于C的高度自由的特点,在OO编程方面还能体现有别于其他语言的特殊韵味。 目 录 - 1. C的面向对象概念 2. 用struct来仿真class 3. 实现OO的继承机制 C的面向对象概念 OO Programing in C is not only POSSIBLE but also PRACTICAL. - OO思想在Unix世界中很早就有:UNIX把设备抽象成文件,这样就可以用一套相同的方法(open, read, write, close, . )去访问不同的设备和文件尽管设备之间的差异很大。用OO的观点来看,这些“设备”对象都实现了"文件操作接口",可以想象有一个叫"文件"的基类,定义了"文件操作接口",“设备”对象继承了“文件”对象.。在实现角度看,在内核里面,设备驱动提供了自己的read, write等实现,并用它们去填充文件操作结构体里面的函数指针.这和C+里面的虚函数运行时绑定的道理是一样的。( C+虚函数是其实是运行时静态绑定,而文件操作接口可以运行时动态绑定 :-) Linux内核中则处处体现了OO的思想。2.6内核的Device Driver Modal是一套层次分明又错综复杂的机制,其中体现了许多OO设计理念。虽然可能设备驱动程序开发者觉察不到,但所有的设备驱动对象内部都隐藏了一个叫 KObject的对象。内核把这些KObjects互相联系在一起,并通过KObject的相互关系构造了/sys文件系统。/sys就是内核中各种设备对象的映射图,如果把/sys全部展开,我们可以清楚地看到各种对象的关系。 实践证明,C也可以很好地用于OO编程,而且可以用于构造很复杂的系统,而且C在表达OO思想的时候并不会显得蹩脚,而是可以很简单,很自然。 用struct来仿真class OO Programing in C is not only POSSIBLE, but also PRACTICAL. - “class“是很多OO编程语言里的关键字,它来源于OO鼻祖Smalltalk。class(类),是对一群有相同特性的对象的抽象概括,对象称为类的实例。在class里面可以存放有状态(变量),行为(函数/方法).有关OO概念、方法的文章太多了,不再啰嗦。在C里面,唯一可以实现自定义类型的是struct,struct是C的OO编程最重要的工具。 一个最常见的技巧,就是用struct来"仿真"class: 在struct里面放入变量,函数指针,嵌入其他struct等。 以下例子摘自我最近刚开发完成的一个USB Firmware项目: C代码 1. struct usb_device; 2. struct usb_ctl; 3. 4. struct usb_iobuf 5. int len; /* data length in the buffer */ 6. unsigned char bufUSBEPFIFO_SIZE; /* data buffer itself */ 7. ; 8. 9. struct usb_endpoint int type; /* endpoint type: BULKIN, BULKOUT, CTL, ISO . */ 10. int qlen; /* queue length */ 11. 12. xQueueHandle lock; /* semaphore lock */ 13. xQueueHandle q; /* data queue (pointer of bulk_buf) */ 14. 15. int idx; /* endpoint index */ 16. int epx; /* endpoint mark bit */ 17. int cfg; /* endpoint configure */ 18. int bank; /* current operation bank (for ping-pong mode) */ 19. int txCount; /* used for ping-pong mode */ /* endpoint data process function */ void (*ep_process) (struct usb_device *dev, struct usb_endpoint *ep, xISRStatus *pxMessage); 20. ; 21. 22. struct usb_descriptor 23. int type; /* descriptor type: device, conf, string or endpoint */ 24. int idx; /* descriptor index (for string descriptor) */ 25. int size; /* descriptor size */ 26. void * data; /* descriptor data */ 27. struct list_head list; /* link list of descriptors */ 28. ; 29. 30. struct usb_deviceOps 31. int (*init)(struct usb_device *dev); /* called when framework init usb device, add device descriptors, init private data . etc. */ 32. int (*reset)(struct usb_device *dev); /* called when reseted by host */ 33. int (*switch_in)(struct usb_device *dev); /* called when switch in */ 34. int (*switch_out)(struct usb_device *dev); /* called when swithc out */ /* called when HOST request class interface data */ 35. void (*class_interface_req)(struct usb_device *dev, xUSB_REQUEST *pxRequest); /* called when HOST complete the data sending stage */ int (*ctl_data_comp)(struct usb_device *dev, xCONTROL_MESSAGE *pxMessage); 36. ; 37. 38. struct usb_ctlOps 39. void (*ctl_transmit_null)(struct usb_ctl *ctl); 40. void (*ctl_send_stall)(struct usb_ctl *ctl); 41. void (*ctl_reset_ep0)(struct usb_ctl *ctl); 42. void (*ctl_detach_usb)(struct usb_ctl *ctl); 43. void (*ctl_attach_usb)(struct usb_ctl *ctl); 44. void (*ctl_send_data)(struct usb_ctl *ctl, unsigned char *data, 45. int req_len, 46. int send_len, 47. int is_des); 48. ; 49. 50. 51. struct usb_ctl 52. int addr; /* address alloced by host */ 53. int conf; /* configuration set by host */ 54. eDRIVER_STATE state; /* current status */ 55. xCONTROL_MESSAGE tx; /* control transmit message */ 56. xCONTROL_MESSAGE rx; /* control receive message */ 57. struct ubufm *bufmn; /* 'usb_iobuf' buffer manager, shared by all usb devices */ 58. int prio; /* the main task priority */ 59. xTaskHandle task_handle; /* the main task handler */ 60. struct usb_ctlOps *ctlOps; /* control endpoint operations */ 61. ; 62. 63. struct usb_devi