面向对象无非就是封装继承和多态
封装:struct实现
继承:指针实现,就是把父类包含在结构体中。
多态:可以用指针实现。
一般实现多态,父结构体必须是子结构体的第一个元素,这样就可以通过强制转换子类和父类随意转换。
结构如:
[cpp] view plaincopy
- struct parent{
- int a;
- };
- struct child{
- struct parent p;
- int b;
- };
- //所以才有下面的转换
- struct child *c=(struct child *)malloc(sizeof(struct child));
- c->p.a=10;
- struct child *c=(struct child *)&(c->p);
- //c语言中有很多这样通过首地址来转换类型的
而linux kernel 的多态不是这样实现的
一般用->和containof()和void *
->:用来得到父类
containof():用来从父类得到子类
void *:相当于java里面的Object类可以把一个类转化为void *,然后在其它地方在转化回来。长用在函数的参数里面。
如:
[cpp] view plaincopy
- #include <stdio.h>
- struct base{
- int a;
- char b;
- };
- struct subclass{
- struct base *mybase;
- int s_a;
- char s_b;
- };
- void test(struct base *base)
- {
- //强制把指向结构体struct base 的指针base转换为指向struct subclass的指针sub
- //这里是向下转型
- //struct subclass *sub=(struct subclass *)base;
- struct subclass *sub=base;
- printf("a:%d\tb:%c\n",sub->mybase->a,sub->mybase->b);
- /*some operations*/
- }
- void main(void)
- {
- struct subclass *mysub=(struct subclass *)malloc(sizeof(mysub));
- mysub->mybase=(struct base *)malloc(sizeof(struct base));
- mysub->mybase->a=10;
- mysub->mybase->b=‘A‘;
- mysub->s_a=11;
- mysub->s_b=‘B‘;
- //这里是向上转型,
- //这个不像java 和 c++那样可以自动向上转型,所有必须手动来,
- //这说的自动不是说如果没有用表达式进行转化的话会出问题,
- //因为我们这里的类不是真正的类,在c++或java中会是有明显的继承如A :base
- struct base *mybase;
- mybase=mysub;
- test(mybase);
- }
ps:一些其它文章
在几何中,所有的几何类型都继承父类“形状(shape)”,父类“形状”有两处属性s_type和s_name。其中s_type用于表示该形状所属的类型,s_name用于表于该形状态的名称。而且父类shape还有两个虚接口,一个为shape_area用于返回该形状的面积,一个为shape_perimeter用于返回该形状的周长。所子继承“形状”的子类都必须实现这两个接口。
- struct shape;
- struct shape_ops
- {
- /*返回几何体的面积*/
- float (*so_area)(struct shape*);
- /*返回几何体的周长*/
- int (*so_perimeter)(struct shape*);
- };
- struct shape
- {
- int* s_type;
- char* s_name;
- struct shape_ops* s_ops; /*虚接口,所有子类必须实现*/
- };
- float shape_area(struct shape* s) /*求形状面积*/
- {
- return s->s_ops->so_area(s);
- }
- int shape_perimeter(struct shape* s) /*求周长*/
- {
- return s->s_ops->so_perimeter(s);
- }
几何体“三角形(triangle)”继承父类“形状”,并且实现了父类的两个虚接口。“三角形”有三条边,分别用t_side_a,t_side_b,t_side_c来表于三条边的长度。
- /*三角形*/
- struct triangle
- {
- struct shape t_base;
- int t_side_a;
- int t_side_b;
- int t_side_c;
- };
- float triangle_area(struct shape* s) /*三角形面积,用海伦公式*/
- {
- struct triangle* t=(struct triangle*)s;
- int a=t->t_side_a;
- int b=t->t_side_b;
- int c=t->t_side_c;
- float p=(a+b+c)/2;
- return sqrt(p*(p-a)*(p-b)*(p-c));
- }
- int triangle_perimeter(struct shape* s) /*三角形周长*/
- {
- struct triangle* t=(struct triangle*)s;
- int a=t->t_side_a;
- int b=t->t_side_b;
- int c=t->t_side_c;
- return a+b+c;
- }
- struct shape_ops triangle_ops= /*对父类虚接口的实现*/
- {
- triangle_area,
- triangle_perimeter,
- };
- struct triangle* triangle_create(int a,int b,int c) /*创建三角形*/
- {
- struct triangle* ret=(struct triangle*)malloc(sizeof (*ret));
- ret->t_base.s_name="triangle";
- ret->t_base.s_ops=&triangle_ops;
- ret->t_side_a=a;
- ret->t_side_b=b;
- ret->t_side_c=c;
- return ret;
- }
几何体“矩形(rectangle)”继承父类“形状”,同样也实现的父类的两个虚接口。有两个属性r_width和r_height,分别表示矩形的长和宽。
- /*矩形*/
- struct rectangle
- {
- struct shape r_base;
- int r_width;
- int r_height;
- };
- float rectangle_area(struct shape* s) /*矩形面积*/
- {
- struct rectangle* r=(struct rectangle*)s;
- return r->r_width*r->r_height;
- }
- int rectangle_perimeter(struct shape* s)/*矩形周长*/
- {
- struct rectangle* r=(struct rectangle*)s;
- return (r->r_width+r->r_height)*2;
- }
- struct shape_ops rectangle_ops= /*对父类虚接口的实现*/
- {
- rectangle_area,
- rectangle_perimeter,
- };
- struct rectangle* rectangle_create(int width, int height) /*创建矩形*/
- {
- struct rectangle* ret=(struct rectangle*)malloc(sizeof(*ret));
- ret->r_base.s_name="rectangle";
- ret->r_base.s_ops=&rectangle_ops;
- ret->r_height=height;
- ret->r_width=width;
- return ret;
- }
测试代码:
- int main()
- {
- struct shape* s[4];
- s[0]=triangle_create(5,5,4);
- s[1]=triangle_create(3,4,5);
- s[2]=rectangle_create(10,12);
- s[3]=rectangle_create(5,8);
- int i=0;
- for(i=0;i<4;i++)
- {
- float area=shape_area(s[i]);
- int perimeter=shape_perimeter(s[i]);
- char* name=s[i]->s_name;
- printf("name:%s ,area:%.2f ,perimeter:%d\n",name,area,perimeter);
- }
- return 0;
- }
运行结果:
- name:triangle ,area:9.17 ,perimeter:14
- name:triangle ,area:6.00 ,perimeter:12
- name:rectangle ,area:120.00 ,perimeter:44
- 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