`
jiagou
  • 浏览: 2517104 次
文章分类
社区版块
存档分类
最新评论

C 语言面向对象编程 理论加实践 代码

 
阅读更多



1.对象定义:

对象的定义包含对象的主要函数,大小,以及引用计数。
必须的函数包括 构造函数,析构函数,比较函数
对象的创建包含两个过程:1). 在堆上分配动态内存。这就是为什么必须填写对象大小的原因 ,对象分配内存后,对象的所有成员会被初始化成0,
2).接下来就调用构造函数初始化对象的成员属性。

2. 对象的析构
对象的析构包含两个过程,1)释放对象的成员,对象的析构函数负责此任务,2)释放对象本身。

3.构造函数
构造函数只负责初始化而不会申请对象内存,对象传给构造函数前已经分配内存。

4.析构函数
析构函数会释放对象的成员,不会释放对象本身,析构函数必须返回对象本身,以便于调用者可以释放对象。
5.引用计数
引用计数用来作垃圾回收,一个定义良好的对象应该包含一个引用计数,用于指示有多少个指向实际对象的引用。
当一个对象被创建时,引用计数初始化为1.当你手动调用ref 及unref此值自动加1减1,当引用计数为0时对象被毁收。
6.继承
我们知道,C语言不支持继承,但是,任何C语言结构本身能够强制指向其第一个元素的指针,这样就可以达到继承的目的。


理论的东西网上一大片,我就不扯了,直接上代码:


spd_obj.h 源码:

#ifndef SPD_OBJECT_H
#define SPD_OBJECT_H

#include <stdarg.h>
#include <stdio.h>


#ifdef __cplusplus extern "C" {

typedef void spd_obj_t;

typedef struct {
// ! The size of the object
size_t size;
spd_obj_t* (*constructor) (spd_obj_t *, va_list *);
spd_obj_t* (*destructor) (spd_obj_t *);
int (*comparator) (const spd_obj_t *, const spd_obj_t *);
} spd_obj_def_t;

/* release obj */
#define SPD_OBJ_SAFE_FREE(obj) if(obj) spd_obj_unref(obj),obj = NULL;

/* base class as is */
#define SPD_OBJ_DECLARE \
const void* __base__; \
size_t refCount;

/* get the definition of the object */
#define SPD_OBJ_DEF(obj) (const (spd_obj_def_t *)obj)

spd_obj_t *spd_obj_new(const spd_obj_def_t *, ...);
size_t *spd_obj_sizeof(const spd_obj_def_t *, ...);
spd_obj_t *spd_obj_ref(spd_obj_t *);
spd_obj_t *spd_obj_unref(spd_obj_t *);
void spd_obj_delete(spd_obj_t *);
spd_obj_t *spd_obj_cmp(const spd_obj_def_t *, const spd_obj_def_t *);
size_t *spd_obj_get_refcount(spd_obj_t *);

}

#endif


spd_obj.c 源码:


#include "spd_obj.h"

typedef struct {
const void *base;
int refCount;
} spd_obj_header_t;

#define SPD_OBJ_HEADER_DEF(obj) (const (spd_obj_header_t*))


spd_obj_t *spd_obj_new(const spd_obj_def_t *obj,...)
{
spd_obj_t *newobj = spd_calloc(1, obj->size);
if(newobj) {
(*(const spd_obj_def_t **) newobj) = obj;
SPD_OBJ_HEADER_DEF(obj)->refCount = 1;
if(obj->constructor) {
va_list ap;
va_start(ap, obj);
newobj = obj->constructor(&newobj, &ap);
va_end(ap);
} else {
spd_log(LOG_WARNING, "must set constructor\n");
}
} else {
spd_log(LOG_ERROR, "failed to alloc\n");
}
return newobj;
}

size_t spd_obj_sizeof(const spd_obj_t *obj)
{
const spd_obj_def_t **objdef = (const spd_obj_def_t **)obj;
if(objdef && *objdef) {
return (*objdef->size;
} else {
spd_log(LOG_ERROR, "NULL OBJ\n");
return 0;
}
}

int spd_obj_cmp(const spd_obj_t *obj1, const spd_obj_t *obj2)
{
const spd_obj_def_t **objdef = (const spd_obj_def_t**)obj2;
if(objdef && *objdef && objdef->comparator) {
return objdef->comparator(obj1, obj2);
}
return -1;
}

spd_obj_t *spd_obj_ref(spd_obj_t *obj)
{
spd_obj_def_t *objhdr = SPD_OBJ_HEADER_DEF(obj);
if(objhdr && objhdr->refCount) {
objhdr->refCount++;
return obj;
}
return NULL;
}

spd_obj_t *spd_obj_unref(spd_obj_t *obj)
{
if(obj) {
spd_obj_header_t *objhdr = SPD_OBJ_HEADER_DEF(obj);
if(objhdr->refCount) {
if(!--objhdr->refCount) {
spd_obj_delete(obj);
return NULL;
}
} else {
return NULL;
}
}
return obj;
}

size_t spd_obj_get_refcount(spd_obj_t *obj)
{
return obj ? SPD_OBJ_HEADER_DEF(obj)->refCount : 0;
}

void spd_obj_delete(spd_obj_t *obj)
{
const spd_obj_def_t **objdef = obj;
if(obj && *obj) {
if((*obj)->destructor) { /* destructor only delete member*/
obj = (objdef)->destructor(obj);
} else {
spd_log(LOG_ERROR, "No destructor found\n");
}
free(obj); /* release obj itself */
}
}




测试代码:

test_obj.c

#include "spd_obj.h"

typedef struct {
SPD_OBJ_DECLARE; /*base class , this is must */

const *name;
struct animal_t *pig;
} animal_t;

/* dog is a type of animal*/
typedef struct {
struct animal_t* animal; /* super class */
char *type;
} dog_t;

/*constructor */
static spd_obj_t* animal_create(spd_obj_t *obj, va_list *app)
{
animal_t *ani = obj;
if(ani) {
ani->name = spd_strdup(va_arg(*app, const char *);
}
return obj;
}

/* destructor */
static spd_obj_t* animal_destroy(spd_obj_t *obj)
{
animal_t *ani = obj;
if(ani) {
spd_free(ani->name);
spd_obj_unref(ani->pig);

}
return obj;
}

static spd_obj_t* animal_cmp(spd_obj_t *obj1, spd_obj_t*obj2)
{
const animal_t *p1 = obj1;
const animal_t *p2 = obj2;

int ret;
if((ret = strcasecmp(p1->name, p2->name))) {
return ret;
}
/* they are all pig ? :-) */
if((ret = spd_obj_cmp(p1->pig, p2->pig))) {
return ret;
}

return 0; /* same */
}

static const spd_obj_def_t animal_def_t = {
sizeof(animal_t),
animal_create,
animal_destroy,
animal_cmp
};

/* the single interface you see */
#define ANIMAL_CREATE(name) spd_obj_new(&animal_def_t, (const char *)name)

static void test_animal()
{
animal_t *candy = ANIMAL_CREATE("Candy");
candy->pig = ANIMAL_CREATE("Sony");
SPD_OBJ_SAFE_FREE(candy);

}

int main(int argc ,char *argv[])
{
test_animal();

return 0;
}



本文来自 csdn lidp 专栏,转载请著名出处,谢谢!



分享到:
评论

相关推荐

    软件工程-理论与实践(许家珆)习题答案

    面向对象的开发方法包括面向对象的分析、面向对象的设计和面向对象的程序设计。( √) 7. 软件危机的主要表现是软件的需求量迅速增加,软件价格上升。(×) 8. 软件工具的作用是为了延长软件产品的寿命。(×) 9. ...

    Python语言程序设计源代码.zip

    使读者在认识物质世界规律的过程中了解计算机的特点、程序设计的特点和人机交互的规律,在认识世界、解释世界和改造世界的实践中掌握Python编程特点、技术和技巧,学会结构化程序设计、面向对象程序设计、人机交互...

    [C大学教程(第五版)].(美)戴特尔.扫描版.pdf

    第24章 面向对象编程:多态 第25章 模板 第26章 输入/输出 第27章 异常处理 附录A 因特网和Web资源、 附录B 运算符优先级表、 附录C ASCLL字符集 附录D 数制系统 附录E 游戏编程:求解Sudoku问题 索引

    编译原理及实践 Kenneth C.Louden 冯博琴

    27 2.2.3 程序设计语言记号的正则表达式 29 2.3 有穷自动机 32 2.3.1 确定性有穷自动机的定义 32 2.3.2 先行、回溯和非确定性自动机 36 2.3.3 用代码实现有穷自动机 41 2.4 从正则表达式到DFA 45 2.4.1 从正则表达式...

    Visual C#程序设计

    并通过大量的程序实例和相关练习逐步掌握高级程序设计语言的基本知识和基本技术,在理论和实践上使学生掌握面向对象的思想方法并初步具备软件开发的能力。全书共17章,内容包括流程控制语句、类与对象 、继承与多态...

    C语言入门经典(第4版)--源代码及课后练习答案

    书中除了讲解C程序设计语言,还广泛介绍了作为一名C程序设计人员应该掌握的必要知识,并提供了大量的实用性很强的编程实例。本书的目标是使你在C语言程序设计方面由一位初学者成为一位称职的程序员。读者基本不需要...

    Visual C#程序设计(2012版)

    本书以Visual C# 2012语言为工具,介绍面向对象程序设计中的基本概念和方法,并通过大量的程序实例和相关练习逐步掌握高级程序设计语言的基本知识和基本技术,在理论和实践上使学生掌握面向对象的思想方法并初步具备...

    敏捷软件开发:原则、模式与实践.pdf

    在 Rational 公司期间,Martin 丰富的实践经验与 Booch 深厚的理论功底形成了完美的组合,把面向对象设计的理论与实践推向了高峰。1994年,Martin的第一本著作《Designing Object-Oriented C++ Application Using ...

    编译原理及实践(需要了解编译原理的可以看看)

    本书系统介绍了经典的编译理论和技术,同时也包含了面向对象语言等当前较新语言的编译技术。 本书更可贵之处在于提供了较完整的适用于教学实践的样例语言,是一本理论和实践内容相结合的、不可多得的好书。 本书可...

    java文件加密解密课程设计.doc

    通过实践加深学生对面" "向对象程序设计的理论、方法和基础知识的理解,掌握使用Java语言进行面向对象设" "计的基本方法,提高运用面向对象知识分析实际问题、解决实际问题的能力,提高学" "生的应用能力。...

    编译原理及实践

    本书系统介绍了经典的编译理论和技术,同时也包含了面向对象语言等当前较新语言的编译技术。本书更可贵之处在于提供了较完整的适用于教学实践的样例语言,是一本理论和实践内容相结合的、不可多得的好书。 本书可...

    Csharp.2008编程参考手册.part1.rar

     ◆C#语言和面向对象编程的基础知识  ◆不同类型的继承以及继承支持代码重用的方式  ◆使用泛型提高应用程序的效率和类型安全性的方式  ◆使用LINQ查询检索数据的方式  ◆使用.NET Framework中的Thread类编写多...

    软件测试(原书中文第二版)

    通过问题、图表和案例研究,对软件测试数学问题和技术进行了深入的研究,并在例子中以更加通用的伪代码取代了过时的Pascal代码,从而使内容独立于具体的程序设计语言。本书还介绍了面向对象测试的内容,并完善了GUI...

    Visual C++串口通信技术详解.(机械工业.李景峰.杨丽娜.潘恒)

    2.1 面向对象程序设计与C++语言 2.1.1 面向对象程序设计概述 2.1.2 C++语言基础 2.1.3 C++的面向对象特性 2.2 Visual C++6.0集成开发环境 2.2.1 visual C++6.0开发环境 2.2.2 项目与项目工作区 2.2.3 应用程序向导...

    代码大全中文版

    本书所面向的对象 本书中所收集的研究和编程经验,将有助于你编写出高质量的软件,并且使得开发周期缩短。通过阅读本书,你将会对自己过去所犯过的错误有更深刻的理解,并懂得今后如何避免它们...

    java课程设计报告贪吃蛇游戏设计.doc

    Java是一个纯的面向对象的程序设计语言,它继 承了 C++ 语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)、多重继承(以接口取代)等特性,增加...

    超市收银程序--(JAVA课程设计-2011).doc

    (JAVA课程设计-2011) 软 件 学 院 课程设计报告书 课程名称 面向对象程序设计 设计题目 超市收银程序 专业班级 学 号 姓 名 "1 设计时间 " "2011.6.6-2011.06.10 " "2 设计目的 " "《面向对象程序设计》是一门实践性...

    c语言内存泄露示例

    与内存相关的编程是如此重要,而在实践中正确应用又是如此困难,以致于它支配着面向对象编程语言、功能性编程语言、高级编程语言、声明性编程语言和另外一些编程语言的所有其他变量或理论。 与少数其他类型的常见...

    编译原理及实现

    本书系统介绍了经典的编译理论和技术,同时也包含了面向对象语言等当前较新语言的编译技术。本书更可贵之处在于提供了较完整的适用于教学实践的样例语言,是一本理论和实践内容相结合的、不可多得的好书。 本书可...

Global site tag (gtag.js) - Google Analytics