c实现面向对象(转)

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

封装:struct实现

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

多态:可以用指针实现。

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

结构如:

[cpp] view plaincopy

  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 plaincopy

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

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;
  2. struct shape_ops
  3. {
  4. /*返回几何体的面积*/
  5. float (*so_area)(struct shape*);
  6. /*返回几何体的周长*/
  7. int (*so_perimeter)(struct shape*);
  8. };
  9. struct shape
  10. {
  11. int* s_type;
  12. char* s_name;
  13. struct shape_ops* s_ops; /*虚接口,所有子类必须实现*/
  14. };
  15. float shape_area(struct shape* s)  /*求形状面积*/
  16. {
  17. return s->s_ops->so_area(s);
  18. }
  19. int shape_perimeter(struct shape* s) /*求周长*/
  20. {
  21. return s->s_ops->so_perimeter(s);
  22. }

几何体“三角形(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

时间: 2024-11-08 23:13:59

c实现面向对象(转)的相关文章

python学习 面向对象封装

from collectoins import namedtuplePoint=namedtuple('point',['x','y'])t1=Point(1,2)print(t1.x)print(t1.y)没有方法的类属性不会发生变化    定义简单 不能改变面向对象封装私有属性!!!私有方法!!!用装饰器描述的几个方法@property !!!@classmethod!!@staticmethod! 封装:class Teacher:     def __init__(self,name,p

python—面向对象的封装

封装 私有属性 class Teacher: __identifier = 'Teacher' #私有静态属性 def __init__(self,name,pwd) self.name = name self.__pwd = pwd #私有属性 内部使用,外部不能使用 def pwd(self): print(self.__pwd) alex = Teacher('alex','3714') alex.pwd() class Teacher: __identifier = 'Teacher'

python学习_day26_面向对象之封装

1.私有属性 (1)动态属性 在python中用双下划线开头的方式将属性隐藏起来.类中所有双下划线开头的名称,如__x都会自动变形成:_类名__x的形式.这种自动变形的特点是: a.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果.b.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的.c.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆

python面向对象知识点疏理

面向对象技术简介 类: 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例.class 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外.类变量通常不作为实例变量使用. 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据. 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写. 实例变量:定义在方法中的变量,只作用于当前实例的类. 继承:即一个派生类(de

php学习笔记 面向对象中[接口]与[多态性]的应用

代码如下: <?php /* 接口技术 * * 接口是一种特殊的抽象类,抽象类又是一种特殊的类 * * 接口和抽象类是一样的作用 * * 因为在PHP是单继承的,如果使用抽象类,子类实现抽象类就不能再去继承其他的类了 * * 如果既想实现一些规范,又想继承其他类.就要使用接口. * * 接口和抽象类的对比 * * 1.作用相同,都不能创建对象,都需要子类去实现 * * 2.接口的声明和抽象类不一样 * * 3.接口被实现方式不一样 * * 4.接口中的所有方法必须是抽象方法,只能声明抽象方法(不

php面向对象

面向对象 什么是面向对象? 面向对象编程(Object Oriented Programming, OOP, 面向对象程序设计)是一种计算机编程架构,OOP的一条基本原则是计算机程 序是由单个能够起到子程序作用的单元或对象组合而成,OOP达到了软件工程的三个目标:重用性.灵活性和扩展性.为了实现整体 运算,每个对象都能够接收信息.处理数据和向其它对象发送信息. 什么是面向对象编程呢? 把每个独立的功能模块抽象成类形成 对象,由多个对象组成这个系统,这些对象之间都能够接收信息.处理数据和向其它对象

面向对象注意事项

在面向对象中,有实例变量和类变量,实例变量为类对象的实例成员,而类变量不仅类可以直接调用,而且类的对象也可以调用.类对象可以对实例变量进行添加.修改.删除操作等... 下面就用个示例来做参考: #!/usr/bin/env python # -*- coding:utf-8 -*- class PersonInfo(object): commity_data = 123 def __init__(self,name,age): self.name = name self.age = age de

java面向对象:面向对象的思想和概述

1:面向对象思想 面向对象是基于面向过程的编程思想. 面向过程:强调的是每一个功能的步骤 面向对象:强调的是对象,然后由对象去调用功能 2:面向对象的思想特点 A:是一种更符合我们思想习惯的思想 B:可以将复杂的事情简单化 C:将我们从执行者变成了指挥者 开发,设计,特征 面向对象开发 就是不断的创建对象,使用对象,指挥对象做事情. 面向对象设计 其实就是在管理和维护对象之间的关系. 面向对象特征 封装(encapsulation) 继承(inheritance) 多态(polymorphism

6 面向对象之类和对象

1 面向对象和面向过程的区别 两者都是软件开发思想,先有面向过程,后有面向对象.在大型项目中,针对面向过程的不足推出了面向对象开发思想. 区别: 1)编程思路不同: 面向过程以实现功能的函数开发为主,而面向对象要首先抽象出类.属性及其方法,然后通过实例化类.执行方法来完成功能. 2)封装性:都具有封装性,但是面向过程是封装的是功能,而面向对象封装的是数据和功能. 3)面向对象具有继承性和多态性,而面向过程没有继承性和多态性,所以面向对象优势是明显. 2 类和对象 对象:客观存在的实体(一个具体的

简说面向过程与面向对象

昨天白天,因为在室外活动,无事可做,所以我思考了一天,在想怎么才能比较清晰的向人解释这两个概念.所以我对这两个概念的字面意思做了一下详细的解释.没想到,这可能真的会帮助我们非常简单的理解这两个概念. 面向:从字面上理解面向,就是我们的脸对着的地方,引申为我们能看到. 过程: 过程是事物从开始,到发展,到结束的整个经历 那么面向过程就是:我们能看到, 一个事物从 开始->发展->结束. 这对于我们写程序的人来说,可能会有感触,因为一开始我们写程序时.都是按照事件的发展.去安排计算机,一步一步的做