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 专栏,转载请著名出处,谢谢!
分享到:
相关推荐
C++语言是面向对象编程的代表性语言之一,由Bjarne Stroustrup在C语言的基础上发展而来,既支持过程化编程,又支持面向对象编程,还引入了模板和STL等高级特性。 本书《面向对象程序设计与C++语言》由朱战立编写,...
C++ 是一种支持面向对象编程的强类型、编译型语言,由Bjarne Stroustrup于1983年在C语言的基础上扩展而成。C++不仅保留了C语言的高效性和灵活性,还引入了类、对象、继承、多态等面向对象特性,使得代码更加模块化和...
《C++面向对象程序设计(第2版)》是谭浩强教授编著的一本经典教材,它深入浅出地介绍了C++编程语言的核心概念和面向对象编程思想。这本书是针对中国高等院校计算机基础教育课程体系规划的一部教材,旨在帮助学生...
这本书深入浅出地讲解了C++语言的核心概念,特别是面向对象编程(OOP)的思想和技术。第二版在第一版的基础上进行了修订和完善,更适应现代编程环境的需求,包含了更多的实践案例和编程练习。 在学习这门课程的过程...
C++ 是一种支持面向对象编程的强类型、编译型语言,由Bjarne Stroustrup于1983年在C语言的基础上发展而来,它不仅继承了C语言的效率和灵活性,还引入了类、对象、封装、继承、多态等面向对象特性。 本教学PPT《面向...
这个压缩包“面向对象程序设计语言C++第2版资源”包含了学习和理解C++的全面资料,特别是对于那些希望通过实践来加深对面向对象编程理解的人来说,这是一个宝贵的资源。 首先,C++是一种静态类型的、编译式的、通用...
面向对象编程是C++语言的核心特性,它引入了类、对象、封装、继承、多态等概念,使得程序设计更加灵活、模块化和易于维护。本资料“C++面向对象程序设计答案”针对清华大学出版社出版的相关教材,提供了课后习题的...
1. **C++语言概述**:C++是由C语言发展而来的一种强类型、静态类型的编程语言,它支持过程化编程、面向对象编程以及泛型编程。C++的设计目标是提供高效、灵活且可移植的代码,它在C语言的基础上增加了类、模板、异常...
《C++面向对象程序设计》是谭浩强教授的一本经典教材,主要针对初学者,深入浅出地讲解了C++编程语言的核心概念和面向对象编程思想。这本书的源代码和高清电子档提供了丰富的学习资源,帮助读者通过实践加深对理论的...
这份资料包含了大量习题及其解答,旨在帮助学习者深入理解和掌握面向对象编程的核心概念。 面向对象程序设计(Object-Oriented Programming, OOP)是现代软件开发中的主流方法论,它基于类和对象的概念,强调数据...
《C编程语言与面向对象基础教程》是一本深入浅出的IT学习资料,涵盖了C语言的基础和面向对象编程的基本概念。C语言是计算机科学中的基石,它的简洁性和强大的底层控制能力使其成为许多系统级开发和嵌入式领域的首选...
通过这个课程设计,学生不仅能够深入理解面向对象编程,还能提升自己在软件工程实践中的全方位技能。这不仅包括需求分析、系统设计、编码实现等硬技能,也包括文档编写、交流沟通等软技能。此外,这种实战性的学习...
在探讨了面向对象编程和设计模式的理论之后,作者将视角转向了软件开发的实际操作,介绍了重构、测试驱动开发(TDD)和持续集成(CI)等现代软件开发流程中的关键实践。重构帮助开发者优化现有代码,提高代码质量;...
《面向对象程序设计与C++语言》这本书将理论与实践相结合,不仅讲解了面向对象的基本概念,还通过C++语言的具体实现帮助读者深入理解面向对象的设计思想。书中可能包含了大量的示例代码和项目案例,帮助学习者更好地...
该书强调了面向对象编程思想,是学习C++编程的重要参考资料。书中的习题代码是辅助读者理解和巩固理论知识的关键实践部分,通过实际编写和运行代码,可以提升编程技能和问题解决能力。 在C++编程中,面向对象编程...
《面向对象程序设计pdf》可能是吴晓涵教授讲解OOP理论和实践的详细教材,配合C/C++源码,读者可以深入理解OOP的实际应用和编程技巧。 通过阅读这本书和分析提供的源码,你将能够: 1. 学习如何定义和使用类,创建...
C++是面向对象编程的重要语言之一,由Bjarne Stroustrup在C语言的基础上发展而来,它既支持过程化编程,又支持面向对象编程。在C++中,对象是类的实例,类定义了对象的数据结构(属性)和行为(方法)。类是抽象数据...
《C#编程语言与面向对象基础教程》是一本专为初学者设计的教材,它深入浅出地介绍了C#这门强大的...通过学习,你不仅能够掌握C#语言的基本语法,还能建立起坚实的面向对象编程基础,为后续的高级开发打下坚实的基础。