用C语言实现面向对象编程
作者:网络转载 发布时间:[ 2013/7/11 10:37:14 ] 推荐标签:
一、类的封装实现:借用高焕堂的宏头文件,类很容易封装为如下的格式
1、类的定义,其中 CLASS() 是 lw_oopc_kc.h 中定义的宏
#include "lw_oopc_kc.h"
CLASS(A)
{
int a; void(*init)(void*,int); void(*put)(void*);
};
2、成员函数的实现
类的封装实质是用借用 struct 结构体,用函数指针来表示 C++中类的方法(成员函数)。接下来给类 A 的方法写实体函数。
void init_A(void *t,int x)
{
A *cthis = (A*)t;
cthis->a = x;
}
void put_A(void*t)
{
A *cthis = (A*)t;
printf(" %d ",cthis->a);
}
3、类(结构体)中的函数指针与实现函数的关联 通过下面的宏把类的方法(函数指针)和实现函数关联:
CTOR(A)
FUNCTION_SETTING (init, init_A); FUNCTION_SETTING (put, put_A);
END_CTOR
4、对象的定义、构造和初始化
如果没有这个连接处理,类(实际是 struct)中的函数指针没有函数的功能。函数 init_A()是 XXX_A() 的命名模式,是指明 XXX_A()属于 A 类的函数,方便程序的理解和维护。下面是要构造 类。在 C++中这个工作系统自动调用构造函数实现而在 C 中,这个过程智能显示调用来实现。借助 lw_oopc_kc.h (或"lw_oopc.h")可以利用宏CLASS_CTOR(class,obj)来将定义的对象进行构造,使之 有数据的同时有方法的功能。实例化一个对象 3 步子如下:
A aa1; // 1、定义对象
CLASS_CTOR(A,aa1); // 2、构造对象—使得函数指针和函数关联
aa1.init(&aa1, 10); // 3、初始化对象的成员变量,注意要: &aa1(取地址)
二、C 继承的实现:
1、子类的定义:在类的开头借用已经定义的类进行定义一个变量,为了更加明白,表明是继承,增加一个宏定义:
#define INHERIT(BASE) IMPLEMENTS(BASE)
于是以类 B 继承类 A 为例子如下:
CLASS(B)
{
INHERIT(A); // 继承 A 类 int b; // 子类的成员 void (*init) (void*, int x);
void (*put) (void*);
};
2、子类的成员函数实现,为了方便辨别,类 B 的成员函数带后缀 ‘_B’
void init_B (void*t, int x, int y)
{
B *cthis = (B*) t;
CLASS_CTOR(A, cthis->A); //----继承的基类在这里构造,对象是 cthis->A cthis->A.init(&cthis->A, x); //----继承的基类的初始化, 注意:&cthis->A cthis->b = y;
}
void put_B (void *t)
{
B *cthis = (B*) t;
cthis->A.put (&cthis->A); //---子类调用父类的方式
printf(" %d ",cthis->b); //---输出类成员值
}
3、子类的构造函数,和无继承类一样,将函数指针和函数关联
CTOR(B)
FUNCTION_SETTING (init, init_B); //---函数指针和函数关联的宏
FUNCTION_SETTING (put, put_B); END_CTOR
说明:对基类的构造,不能在子类的构造宏 CTOR(B) 和 END_CTOR 之间进行,因为那时候子类 B 没有实例化,故没有实体对象,CLASS_CTOR(A, cthis->A);不能放在里面,只好放在 init_B() 函数里面,因为那时候 B 类已经有实例化对象了。这样的做法与 C++的做法不一样。C++在构造 B 的对象时,先调用 A 类的构造函数实例化对象中的基类部分。下面为main()函数的调用处理:
int main()
{
A aa1; B b;
CLASS_CTOR(A,aa1); //--构造 aa1 对象 aa1.init(&aa1,5); //--初始化 aa1 对象aa1.put(&aa1); //--调用 aa1 对象的成员函数
CLASS_CTOR(B, b); //---构造 b 对象
b.init(&b,100,78); //--初始化 b 对象,包括基类 A 的构造和初始化
b.put(&b); //--调用 b 对象成员函数
b.A.put(&b.A); //--调用 b 对象的基类成员函数
return 0;
}
输出结果为:5 100 78 100
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11