c实现面向对象

 

c实现面向对象

分类: embedded system   1713人阅读  评论(0)  收藏  举报

面向对象无非就是封装继承和多态

封装:struct实现

继承:指针实现,就是把父类包含在结构体中。

多态:可以用指针实现。

一般实现多态,父结构体必须是子结构体的第一个元素,这样就可以通过强制转换子类和父类随意转换。

结构如:

接口在 C 语言中,表现为一组函数指针的集合。放在 C++ 中,即为虚表。C++ 通过纯虚基类实现接口  使用struct组合函数指针就可以实现纯虚类

[cpp]  view plain copy
  1. struct parent{  
  2.         int a;  
  3. };  
  4. struct child{  
  5.        struct parent p;  
  6.        int b;  
  7. };  
  8. //所以才有下面的转换  
  9. struct child *c=(struct child *)malloc(sizeof(struct child));  
  10. c->p.a=10;  
  11. struct child *c=(struct child *)&(c->p);  
  12. //c语言中有很多这样通过首地址来转换类型的  


而linux kernel 的多态不是这样实现的

一般用->和containof()和void *

->:用来得到父类

containof():用来从父类得到子类

void *:相当于java里面的Object类可以把一个类转化为void *,然后在其它地方在转化回来。长用在函数的参数里面。

如:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2.   
  3. struct base{  
  4.     int a;  
  5.     char b;  
  6. };  
  7.   
  8. struct subclass{  
  9.     struct base *mybase;  
  10.     int s_a;  
  11.     char s_b;  
  12. };  
  13.   
  14.   

  15. void test(struct base *base)  
  16. {  
  17.     //强制把指向结构体struct base 的指针base转换为指向struct subclass的指针sub  
  18.     //这里是向下转型  
  19.     //struct subclass *sub=(struct subclass *)base;  
  20.     struct subclass *sub=base;  
  21.     printf("a:%d\tb:%c\n",sub->mybase->a,sub->mybase->b);  
  22.     /*some operations*/  
  23. }  
  24.   
  25. void main(void)  
  26. {  
  27.     struct subclass *mysub=(struct subclass *)malloc(sizeof(mysub));  
  28.     mysub->mybase=(struct base *)malloc(sizeof(struct base));  
  29.     mysub->mybase->a=10;  
  30.     mysub->mybase->b='A';  
  31.     mysub->s_a=11;  
  32.     mysub->s_b='B';  
  33.     //这里是向上转型,  
  34.         //这个不像java 和 c++那样可以自动向上转型,所有必须手动来,  
  35.     //这说的自动不是说如果没有用表达式进行转化的话会出问题,  
  36.     //因为我们这里的类不是真正的类,在c++或java中会是有明显的继承如A :base  
  37.     struct base *mybase;  
  38.     mybase=mysub;  
  39.     test(mybase);  
  40. }  

ps:一些其它文章

来自:http://blog.chinaunix.net/uid-26750235-id-3102371.htmlhttp://blog.chinaunix.net/uid-26750235-id-3102371.html

      在几何中,所有的几何类型都继承父类“形状(shape)”,父类“形状”有两处属性s_type和s_name。其中s_type用于表示该形状所属的类型,s_name用于表于该形状态的名称。而且父类shape还有两个虚接口,一个为shape_area用于返回该形状的面积,一个为shape_perimeter用于返回该形状的周长。所子继承“形状”的子类都必须实现这两个接口。
  1. struct shape;
// 这里实现了纯虚函数,具体函数的实现由子类来实现
  1. struct shape_ops
  2. {
  3.     /*返回几何体的面积*/
  4.     float (*so_area)(struct shape*); 
  5.     /*返回几何体的周长*/
  6.     int (*so_perimeter)(struct shape*);
  7. };
  8. struct shape
  9. {
  10.     int* s_type;
  11.     char* s_name;
  12.     struct shape_ops* s_ops; /*虚接口,所有子类必须实现*/
  13. };


// 这个函数类似 模型方法:专门调用父类/子类里面的函数,在c++里面只要把基类传进来,就能进行相关的函数调用了
//  父类定义了纯虚函数,这类实现纯虚函数并且把实现的函数指针赋给了纯虚函数,这样调用的时候,直接调用父类的纯虚函数,这样就自动调用了子类实现的函数
  1. float shape_area(struct shape* s)  /*求形状面积*/
  2. {
  3.     return s->s_ops->so_area(s);  
  4. }
  5. int shape_perimeter(struct shape* s) /*求周长*/
  6. {
  7.     return s->s_ops->so_perimeter(s);
  8. }
        几何体“三角形(triangle)”继承父类“形状”,并且实现了父类的两个虚接口。“三角形”有三条边,分别用t_side_a,t_side_b,t_side_c来表于三条边的长度。
  1. /*三角形*/
  2. struct triangle
  3. {
  4.     struct shape t_base;
  5.     int t_side_a;
  6.     int t_side_b;
  7.     int t_side_c;
  8. };

  9. float triangle_area(struct shape* s)  /*三角形面积,用海伦公式*/
  10. {
  11.     struct triangle* t=(struct triangle*)s;
  12.     int a=t->t_side_a;
  13.     int b=t->t_side_b;
  14.     int c=t->t_side_c;
  15.     float p=(a+b+c)/2;
  16.     return sqrt(p*(p-a)*(p-b)*(p-c));
  17. }
  18. int triangle_perimeter(struct shape* s)  /*三角形周长*/
  19. {
  20.     struct triangle* t=(struct triangle*)s;
  21.     int a=t->t_side_a;
  22.     int b=t->t_side_b;
  23.     int c=t->t_side_c;
  24.     return a+b+c;
  25. }
  26. struct shape_ops triangle_ops=    /*对父类虚接口的实现*/
  27. {
  28.     triangle_area,
  29.     triangle_perimeter,
  30. };
  31. struct triangle* triangle_create(int a,int b,int c)  /*创建三角形*/
  32. {
  33.     struct triangle* ret=(struct triangle*)malloc(sizeof (*ret));
  34.     ret->t_base.s_name="triangle";
  35.     ret->t_base.s_ops=&triangle_ops;
  36.     ret->t_side_a=a;
  37.     ret->t_side_b=b;
  38.     ret->t_side_c=c;
  39.     return ret;
  40. }
        几何体“矩形(rectangle)”继承父类“形状”,同样也实现的父类的两个虚接口。有两个属性r_width和r_height,分别表示矩形的长和宽。
  1. /*矩形*/
  2. struct rectangle
  3. {
  4.     struct shape r_base;
  5.     int r_width;
  6.     int r_height;
  7. };

  8. float rectangle_area(struct shape* s)  /*矩形面积*/
  9. {
  10.     struct rectangle* r=(struct rectangle*)s;
  11.     return r->r_width*r->r_height;
  12. }
  13. int rectangle_perimeter(struct shape* s)/*矩形周长*/
  14. {
  15.     struct rectangle* r=(struct rectangle*)s;
  16.     return (r->r_width+r->r_height)*2;
  17. }
  18. struct shape_ops rectangle_ops=      /*对父类虚接口的实现*/
  19. {
  20.     rectangle_area,
  21.     rectangle_perimeter,
  22. };

  23. struct rectangle* rectangle_create(int width, int height)  /*创建矩形*/
  24. {
  25.     struct rectangle* ret=(struct rectangle*)malloc(sizeof(*ret));
  26.     ret->r_base.s_name="rectangle";
  27.     ret->r_base.s_ops=&rectangle_ops;
  28.     ret->r_height=height;
  29.     ret->r_width=width;
  30.     return ret;
  31. }
测试代码:
  1. int main()
  2. {
  3.     struct shape* s[4];
  4.     s[0]=triangle_create(5,5,4);
  5.     s[1]=triangle_create(3,4,5);
  6.     s[2]=rectangle_create(10,12);
  7.     s[3]=rectangle_create(5,8);

  8.     int i=0;
  9.     for(i=0;i<4;i++)
  10.     {
  11.         float area=shape_area(s[i]);    
  12.         int perimeter=shape_perimeter(s[i]);
  13.         char* name=s[i]->s_name;

  14.         printf("name:%s ,area:%.2f ,perimeter:%d\n",name,area,perimeter);
  15.     }
  16.     return 0;
  17. }

运行结果:
  1. name:triangle ,area:9.17 ,perimeter:14
  2. name:triangle ,area:6.00 ,perimeter:12
  3. name:rectangle ,area:120.00 ,perimeter:44
  4. name:rectangle ,area:40.00 ,perimeter:26

来自:http://blog.csdn.net/kennyrose/article/details/7564105

最近百度面试过程中有同学被问到这样一个问题:如何用C语言实现面向对象?我们都知道面向对象的三大基本特征:封装、继承和多态,C++语言和编译器都对这些特征有着强有力的支持,但是对于C这样的函数式语言,如何实现面向对象?引用一句话:面向对象从来都是思想,而不是语言! 理解面向对象的编程思想,我们使用C语言这样的较低级的语言也同样可以实现OOP,里面具体用到的有C语言中的宏,结构体,函数指针, 聚合组合等知识。


强烈推荐参阅以下链接


http://blog.codingnow.com/2010/03/object_oriented_programming_in_c.html

http://c.group.iteye.com/group/wiki/1291-object-oriented-programming-language-c

http://blog.chinaunix.net/uid-26750235-id-3102371.html

http://blog.chinaunix.net/uid-9104650-id-2009591.html

http://liujian.is-programmer.com/posts/268.html

http://blog.csdn.net/yuyin86/article/details/7107671#




推荐两本书:

《   Inside the C++ Object Model  》

《 Object-oriented Programming with ANSI-C 》


这里是csdn上前几章的中文翻译

http://blog.csdn.net/besidemyself/article/details/6376405


wiki上有全部的中英文互译

http://wiki.chinaunix.net/OOC:%e5%86%85%e5%ae%b9


不过建议对照英文原著阅读

http://www.planetpdf.com/codecuts/pdfs/ooc.pdf


这里有Object-oriented   Programming   with   ANSI-C的一些例子

http://www.bolthole.com/OO-C-programming.html

http://barracudaserver.com/WP/DeviceControl/OOIntro.html

http://www.eventhelix.com/realtimemantra/basics/object_oriented_programming_in_c.htm



这里是一些OOP设计思想和原则的文章

http://www.eventhelix.com/realtimemantra/Object_Oriented/


下面这篇给出了C++和对应的C代码,用C来实现C++中的继承和虚函数特性,推荐@ ^ @

http://www.eventhelix.com/realtimemantra/basics/ComparingCPPAndCPerformance2.htm


下面是一个轻量级的面向对象C编程框架LW——OOPC(Light Weight Object-oriented Programming with C)

http://sourceforge.net/projects/lwoopc/


下面是优酷上面的一个视频教程(我还没看)

http://v.youku.com/v_show/id_XMTM4MzkyMTI4.html


不小心搜到了一个《 C语言也能干大事 》

http://www.rupeng.com/forum/forum-52-1.html

 

有兴趣的话也可以学习一下 Objective-C,它是加入面向对象思想的C语言母集

http://zh.wikipedia.org/wiki/Objective-C

http://www.apple.com.cn/developer/mac/library/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/chapter_1_section_1.html#//apple_ref/doc/uid/TP40005149-CH1-SW2


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值