Chinaunix首页 | 论坛 | 博客
  • 博客访问: 845891
  • 博文数量: 756
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 4980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:40
文章分类

全部博文(756)

文章存档

2011年(1)

2008年(755)

我的朋友

分类:

2008-10-13 16:09:56

 今天论坛上有人在问,如何用c 实现c++的继承, 我告诉他是结构加指针实现,虽然表达简单,但的确需要这两样东西,
    另外感觉继承主要好处就是实现多态性,那用c实现了多态性,估计也就用到了继承的优点
 以前是在vc编程难点剖析一书里看到过用c实现多态性的的方法,说到这本书还是要表扬一下的,vc编程难点剖析这本书写得很不错的,那时在新风雨,打5折买的,看来好东西,不一定价高,那本书的源码很简单,如下:
#include "stdio.h"
#include "stdlib.h"

//定义函数指针类型DISPLAYINTEGER,指向返回值为void,参数列表为(const int)的函数
typedef  void( *DISPLAYINTEGER)(const int);

//定义函数,将数字以十进制形式输出,该函数类型与DISPLAYINTEGER匹配
void DisplayDecimal(const int Number)
{
 printf("The decimal value is %d\n",Number);
}
//定义函数,将数字以八进制形式输出,该函数类型与DISPLAYINTEGER匹配
void DisplayOctal(const int Number)
{
 printf("The octal value is %o\n",Number);
}
//定义函数,将数字以十六进制形式输出,该函数类型与DISPLAYINTEGER匹配
void DisplayHexadecimal (const int Number)
{
 printf("The hexadecimal value is %x\n",Number);
}
/********************************************************************
定义通用的显示数字函数
DisplayFormat  DISPLAYINTEGER函数指针类型,实参可以是以上定义的
      三个函数之一。通过传递不同的实参,将数字以各种格式输出。
Number        准备输出的数字
********************************************************************/
void DisplayNumber(DISPLAYINTEGER  DisplayFormat,const int Number)
{
  //调用以实参传入的函数,以某种格式输出整型数字
 DisplayFormat(Number);
}

int main(int argc, char* argv[])
{
 int Number=0;

// 如果有数字形式的命令行参数,将其输出,否则输出0
   if(argc>1)  
        Number=atoi(argv[1]);
   //分别以三种格式将数字输出
 DisplayNumber(DisplayDecimal,Number);
    DisplayNumber(DisplayOctal,Number);
    DisplayNumber(DisplayHexadecimal,Number);

 return 0;
}
看起来通俗易懂,不过没有继承 的感觉

以前还在其他地方看到过类似c 实现继承的代码
下午我就简化了一段代码,并且编译执行了下,来实现c 的所谓继承,代码如下:
1.parent.h
#ifndef PARENT_H
#define PARENT_H

#include "child1.h"
#include "child2.h"


struct parent_type{
   unsigned int id;
   //char classname[20];
   char * name;
   struct{
     struct parent_handle * (*init)(void * pvoid);
     int (*fp1)(struct parent_handle *ph);
     //...
   }pfn;
   struct parent_type *next;
};


struct parent_handle{
    int i;
    union{
      struct child1_handle child_hdl1;
      struct child2_handle child_hdl2;
      //...
    }priv;
    struct parent_type *ptp;
};

2.parent.h

#include "stdafx.h"

#include "parent.h"

static struct parent_type *class_list;

int register_child(struct parent_type *p)
{
 p->next = class_list;
 class_list = p;
 return 0;
}

struct parent_handle * parent_init(void * pchild_priv, unsigned int id)
{
 struct parent_type *p;

 for (p = class_list; p; p = p->next)
  if (p->id == id)
   return p->pfn.init(pchild_priv);

 printf("unable to find matching child class\n");
 return NULL;
}

int parent_fp1(struct parent_handle *ph)
{
 if (!ph->ptp->pfn.fp1)
  return 0;

 return ph->ptp->pfn.fp1(ph);
}


int register_child(struct parent_type *p);

struct parent_handle * parent_init(void * pchild_priv, unsigned int id);

int parent_fp1(struct parent_handle *ph);


#endif

3. child1.h
#ifndef CHILD1_H
#define CHILD1_H

#define CHILD_1_ID 101

struct child1_handle
{
  char child1_decr[20];
  int  child1_data;
  //...
};

extern struct parent_type child_tp1;

struct parent_handle * child1_init(void * pvoid);
int child1_fp1(struct parent_handle *ph);

#endif

4.child1.c
#include "stdafx.h"

#include "parent.h"
#include "child1.h"


struct parent_type child_tp1= {CHILD_1_ID,"class child1",{&child1_init,&child1_fp1},0};
/*
struct parent_type  child1= {
 .id = CHILD_1_ID,
 .name  = "class child1",
 .fn = {
  .init   = &child1_init,
  .fp1   = &child1_fp1,
 },
};
*/


struct parent_handle * child1_init(void * pvoid)
{
 //int ret;
 struct child1_handle *h;
 struct parent_handle *ph = (struct parent_handle *)malloc(sizeof(struct parent_handle/* *h */));
 if (!ph)
  return NULL;
 ph->ptp = &child_tp1;

     //todo
  h = &ph->priv.child_hdl1;
  strcpy(h->child1_decr,"hello child1!");
  h->child1_data=*((int*)(pvoid));
     //...
 return ph;
}


int child1_fp1(struct parent_handle *ph)
{
  struct child1_handle *h = &ph->priv.child_hdl1;
  //todo
  printf("%s,data=%d\r\n",h->child1_decr,h->child1_data);
  //...

  return 0;
}

5.child2.h

#ifndef CHILD2_H
#define CHILD2_H


#define CHILD_2_ID 102

struct child2_handle
{
  int  child2_data;
  char child2_decr[20];
  //...
};

extern struct parent_type child_tp2;

int child2_fp1(struct parent_handle *ph);
struct parent_handle * child2_init(void * pvoid);

#endif

6.child2.c
#include "stdafx.h"

#include "parent.h"
#include "child2.h"


struct parent_type child_tp2= {CHILD_2_ID,"class child2",{&child2_init,&child2_fp1},0};
/*
struct parent_type  child1= {
 .id = CHILD_1_ID,
 .name  = "class child1",
 .fn = {
  .init   = &child1_init,
  .fp1   = &child1_fp1,
 },
};
*/


struct parent_handle * child2_init(void * pvoid)
{
 //int ret;
 struct child2_handle *h;
 struct parent_handle *ph = (struct parent_handle *)malloc(sizeof(struct parent_handle/* *h */));  //别忘了自己加deinit 把它释放
 if (!ph)
  return NULL;
 ph->ptp = &child_tp2;

     //todo
  h = &ph->priv.child_hdl2;
  strcpy(h->child2_decr,"hello child2!");
  h->child2_data=*((int*)(pvoid));
     //...
 return ph;
}


int child2_fp1(struct parent_handle *ph)
{
  struct child2_handle *h = &ph->priv.child_hdl2;

  //todo
  printf("%s,data=%d\r\n",h->child2_decr,h->child2_data);
  //...

  return 0;
}

最后是main.c

// testClass.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "parent.h"
#include "child1.h"
#include "child2.h"

static struct parent_handle *pchild_1_h,*pchild_2_h;

int main(int argc, char* argv[])
{
 //printf("Hello World!\n");
   int child1_priv=123;
   int child2_priv=456;
   register_child(&child_tp1);                 //注册子类1
   pchild_1_h = parent_init((void *)(&child1_priv),CHILD_1_ID);      //初始化子类1
   if(pchild_1_h)
     parent_fp1(pchild_1_h);                     //执行子类1的fp1函数

   register_child(&child_tp2);                 //注册子类2
   pchild_2_h = parent_init((void *)(&child2_priv),CHILD_2_ID);      //初始化子类2
   parent_fp1(pchild_2_h);                     //执行子类2的fp1函数
 return 0;
}

 

/*
用c++实现很简单
class parent
{
    virturl int fp1 ();
}

 class child1 :public parent
 {
    char child1_decr[20];
    int  child1_data;
     int fp1 ();

 }

 class child2 :public parent
 {
    char child2_decr[20];
    int  child2_data;
     int fp1 ();

 }


  parent * pa;
  child1 ch1b;
  
   pa= ch1b;

   pa->fp1;

*/

用c实现一些类似c++的功能还是有好处的,一方面多重继承开销大,而且在底层编程,c 用得比较多,所以总结了下,以后可能有点用


--------------------next---------------------

阅读(272) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~