用C实现C++的多态---剖析GTK的"对象" (三)

原创 2006年06月15日 10:05:00

六. 全部代码

/***********************************************************************

object.h文件

************************************************************************/
#ifndef _H_OBJECT_H_
#define _H_OBJECT_H_

#define TOP_OBJECT_TYPE  0
#define BASE_OBJECT_TYPE  GetObjectType()
#define IS_OBJECT_TYPE(obj)  IsObjectType(obj,BASE_OBJECT_TYPE)
#define BASE_OBJECT_CLASS(obj) ((CObjectClass*)GetObjectClass(obj))

typedef void (*pInitObjectCallback)(void*);
typedef void (*pInitClassCallback)(void*);

typedef struct _CObject  CObject;
typedef struct _CObjectClass CObjectClass;
typedef struct _ClassInfo  ClassInfo;

struct _CObject
{
 CObjectClass *vclass;
 short  ref_counter;
};

struct _CObjectClass
{
 int class_type;
 void (*destory)(CObject *object);
};

struct _ClassInfo
{
 char    *name;
 int     object_size;
 int     class_size;
 void (*InitObjectCallback)(void*);
 void (*InitClassCallback)(void *);
};

#ifdef __cplusplus
extern "C" {
#endif

int
GetObjectType(void);

void*
GetObjectClass(void *);

CObject *
NewObject(void);

void
DestoryObject(CObject *object);

void
AttachObject(CObject *object);

void
ReleaseObject(CObject *object);

 

void
InitObjectLib(void);

int
RegisterClassType(ClassInfo *classinfo, int parent_type);

void*
NewClassType(int class_type);

int
IsObjectType(void *obj, int type);

int
CheckClassType(int type);

#ifdef __cplusplus
}
#endif
#endif

 


/***********************************************************************

object.c文件

************************************************************************/

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "object.h"
#include "tvstring.h"
#include "debug.h"

#define MAX_CLASS_NUM  128
#define lock()
#define unlock()

typedef struct _ClassType
{
 char*    name;
 int     class_size;
 int     object_size;
 CObjectClass*  vclass;
 void (*InitClassCallback)(void*);
 void (*InitObjectCallback)(void*);
 struct _ClassType* parent;
 struct _ClassType* next;
}ClassType;

static ClassType classes[MAX_CLASS_NUM];
static ClassType *used_classes = NULL;
static ClassType *free_classes = NULL;

 


/****************************************************************/

static void
InitObjectClass(CObjectClass *vclass)
{
 if(vclass==NULL)
  return;
 
 vclass->destory = DestoryObject;
}

static void
InitObject(CObject *object)
{
 if(object==NULL)
  return;
 
 object->ref_counter = 1;
}

int
GetObjectType(void)
{
 static int type = 0;

 if( type==0 )
 {
  static ClassInfo classinfo =
  {
   "OBJECT",
   sizeof(CObject),
   sizeof(CObjectClass),
   (pInitObjectCallback)InitObject,
   (pInitClassCallback)InitObjectClass,
  };

  type = RegisterClassType(&classinfo, TOP_OBJECT_TYPE);
 }

 return type;
}

void*
GetObjectClass(void *obj)
{
 CObject *object;

 if(obj==NULL)
  return NULL;
 
 object = (CObject *)obj;
 return (void*)object->vclass;
}


CObject *
NewObject(void)
{
 return NewClassType(BASE_OBJECT_TYPE);
}

void
DestoryObject(CObject *object)
{
 if(object==NULL)
  return;
 
 free(object);
}

void
AttachObject(CObject *object)
{
 if(object==NULL)
  return;

 object->ref_counter++;
}

void
ReleaseObject(CObject *object)
{
 if(object==NULL)
  return;

 if( --object->ref_counter==0 )
  DestoryObject(object);
}


/****************************************************************/
void
InitObjectLib(void)
{
 int i;
 memset(classes, 0, sizeof(ClassType)*MAX_CLASS_NUM);
 for( i=0;i<MAX_CLASS_NUM-1;i++ )
 {
  classes[i].next = &(classes[i+1]);
 } 
 free_classes = &(classes[0]);
}

int
RegisterClassType(ClassInfo *classinfo, int parent_type)
{
 int type = 0;
 ClassType *current, *parent;

 {
  parent = (ClassType *)parent_type;

 #ifdef __DEBUG 
  if( parent &&parent->vclass==NULL )
  {
   TRACE("RegisterClassType(): parent_type is invalid/n");
   return type;
  }
 #endif

  if( classinfo->name==NULL )
  {
   TRACE("RegisterClassType(): class name is NULL/n");
   return type;
  }

  lock();
  current = used_classes;
  while(current)
  {
   if(strcmp(current->name, classinfo->name)==0 )
   {
    TRACE("RegisterClassType(): class name is redefined/n");
    unlock();
    return type;
   }
   current = current->next;
  }

  current = free_classes;
  if(current)
  {
   free_classes = free_classes->next;
   current->name = classinfo->name;
   current->parent = parent;
   current->class_size = classinfo->class_size;
   current->InitClassCallback = classinfo->InitClassCallback;
   current->InitObjectCallback = classinfo->InitObjectCallback;
   current->vclass = malloc(current->class_size);
   if( current->vclass==NULL )
   {
    TRACE("RegisterClassType(): malloc vclass failed/n");
   }
   memset( current->vclass, 0, current->class_size);
   current->vclass->class_type = (int)current;
   if( parent )
   {
    memcpy(current->vclass, parent->vclass, parent->class_size);
   }
   if( current->InitClassCallback )
    current->InitClassCallback(current->vclass);
   current->next = used_classes;
   used_classes = current;
  }
  else
  {
   TRACE("RegisterClassType(): ERROR, no class in class pool/n");
  }

  unlock();
 
  type = (int)current;
 }

 return type;
}

static void
InitParentObject(ClassType *current, void *object)
{
 if( current )
 {
  if( current->parent )
   InitParentObject(current->parent, object);
  if( current->InitObjectCallback )
   current->InitObjectCallback(object);
 }
}

void *
NewClassType(int class_type)
{
 ClassType *pclass = NULL;
 void *object = NULL;

 if( pclass==0 )
  return NULL;

 #ifdef __DEBUG
 if( CheckClassType(class_type)==0 )
 {
  TRACE("NewObjectType(): invalid class_type/n");
  return NULL;
 }
 #endif
 
 pclass = (ClassType*)class_type;
 object = (CObject*)malloc(pclass->object_size);
 if( object )
 {
  ((CObject*)object)->vclass = pclass->vclass;
  InitParentObject(pclass, object);
 }

 return object;
}

int
IsObjectType(void *obj, int type)
{
 ClassType *pclass, *objtype;
 CObject *object;
 
 if( obj==NULL || type==0 )
  return 0;

 pclass = (ClassType*)type;
 object = (CObject*)obj;
 if( object->vclass==NULL )
  return 0;

 objtype = (ClassType*)object->vclass->class_type;
 while(objtype)
 {
  if( objtype==pclass )
   return 1;
  objtype = objtype->parent;
 }

 return 0;
}

int
CheckClassType(int type)
{
 ClassType *objtype;
 
 objtype = used_classes;
 while(objtype)
 {
  if( (int)objtype==type )
   return 1;
  objtype = objtype->next;
 }
 return 0;
}

 

 

C语言实现C++面向对象语言多态特性

我们知道,C++语言演化过程中,加入了不少新特性,使其成为一门现代高级OO语言。当初C++在上个世纪七十年代末,80年代初时,C++发展刚刚起步,那时C++可以看作C with class,C++编写...
  • sunjunior
  • sunjunior
  • 2016年03月09日 21:02
  • 1298

如何用C语言实现类似C++中的多态

先引用一篇博文,讲讲什么是多态: C++编程语言是一款应用广泛,支持多种程序设计的计算机编程语言。我们今天就会为大家详细介绍其中C++多态性的一些基本知识,以方便大家在学习过程中对此能够有一个充分的...
  • samuel_chen
  • samuel_chen
  • 2014年12月12日 14:42
  • 1207

C语言模拟实现C++的继承与多态

一、面向过程编程与面向对象编程的区别 众所周知,C语言是一种典型的面向过程编程语言,而C++确实在它的基础上改进的一款面向对象编程语言,那么,面向过程与面向对象到底有什么样的区别呢?【...
  • snow_5288
  • snow_5288
  • 2017年04月16日 21:28
  • 1159

C语言模式实现C++继承和多态

这个问题主要考察的是C和C++的区别,以及C++中继承和多态的概念。C和C++的区别C语言是面向过程的语言,而C++是面向对象的过程。什么是面向对象和面向过程? 面向过程就是分析解决问题的步骤,然后用...
  • wenqiang1208
  • wenqiang1208
  • 2017年07月28日 12:36
  • 698

c++面向对象三大特征封装、继承和多态知识总结

面向对象三大特征:封装,继承,多态; 一、封装:该公开的就公开话,该私有的就隐藏掉,主要是由public,private实现;作用是便于分工和分模块,防止不必要的扩展; 二、继承:就是一种传承,可以把...
  • uestclr
  • uestclr
  • 2016年06月05日 18:23
  • 2881

如何用c语言实现多态

前几天在小组无意见听到学姐说到c语言实现多态这个词,比较感兴趣,欢迎一起讨论哈。 提前说一下,c实现多态算是一个奇怪的用法吧,而且不是完全的多态,并不通用,也不推荐用。感兴趣的可以了解下 我们都知...
  • wwh578867817
  • wwh578867817
  • 2015年04月17日 19:24
  • 2356

C++多态的实现方式总结

实现多态有两种方法: 1、覆盖 *********** 覆盖是指子类重新定义父类的虚函数的做法。 2、重载 *********** 重载是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数...
  • sinat_20265495
  • sinat_20265495
  • 2015年11月30日 14:45
  • 3060

Java-面向对象编程-三大特性之多态

我们前面已经介绍了面向对象编程的三大特性之二,今天就介绍最后一个特性-多态。 什么叫多态?从字面上理解就是多种形态,即对同一个客体,可以有多种不同的形式。就好像糖一样,有多种口味,你想吃什么口味的就...
  • dengminghli
  • dengminghli
  • 2017年02月01日 18:14
  • 3425

java提高篇(三)-----理解java的三大特性之多态

面向对象编程有三大特性:封装、继承、多态。        封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据。对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访...
  • chenssy
  • chenssy
  • 2013年10月16日 19:44
  • 57523

C++中的多态在C中如何实现

多态的含义约等同于“同一个方法对于不同类型的输入参数均能做出正确的处理过程,并给出人们所期望获得的结果” C++的多态性是C++实现面向对象技术的基础。具体的说,通过一个指向基类的指针调用虚成员...
  • firefly_2002
  • firefly_2002
  • 2012年09月18日 19:47
  • 3305
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用C实现C++的多态---剖析GTK的"对象" (三)
举报原因:
原因补充:

(最多只允许输入30个字)