用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++对象布局及多态实现

  • 2008年05月12日 20:35
  • 34KB
  • 下载

C/C++:面向对象编程特性:多态(虚函数表原理)

#include #include using namespace std; //定义两个函数指针类型 typedef void(*pFunc)(void); typedef int(*pSum...
  • jiezhj
  • jiezhj
  • 2014年08月05日 14:54
  • 515

面向对象多态c++

  • 2013年04月16日 07:56
  • 436KB
  • 下载

Objective-C基础(面向对象--下--三大特性--继承、多态)

一、继承        1. 为什么要使用继承呢?             1)先看一个例子:                   声明一个Person类 #import @interface Pe...
  • huhanze
  • huhanze
  • 2015年01月23日 10:59
  • 289

objective-c自学总结(三)---面向对象的封装,继承与多态

面向对象的三大特性: 封装:隐藏属性,方法或实现细节的过程称为封装 继承 多态 1封装: 信息隐藏,隐藏对象的实现细节,不允许用户看到 将东西包装在一 然后以新的完整形式呈现出来 例如,两种或...

Objective-C基础学习笔记(五)-面向对象的三大特性之多态

一.什么是多态?  1. 多态的字面意思就是,指同一个实体同时具有多种形态。它是面向对象程序设计(OOP)的一个重要特征,Objective-C作为面向对象的语言,OC的对象也具有多态性,多态在代码中...

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

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

C++ —面向对象之多态的实现与应用

多态 今天我们的主角就是多态了,那么什么多态呢?多态有什么用? 多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程...
  • Dawn_sf
  • Dawn_sf
  • 2017年04月05日 09:49
  • 582

C++对象布局及多态实现的探索(六)

C++对象布局及多态实现的探索(六) 后记   结合前面的讨论,我们可以看到,只要牵涉到了虚继承,在访问父类的成员变量时生成的代码相当的低效,需要通过很多间接的计算来定位成员变量的...
  • ilvu999
  • ilvu999
  • 2012年09月05日 00:14
  • 580
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用C实现C++的多态---剖析GTK的"对象" (三)
举报原因:
原因补充:

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