设计模式学习及其C语言实现笔记

上传人:枫** 文档编号:485681862 上传时间:2023-12-20 格式:DOC 页数:30 大小:141KB
返回 下载 相关 举报
设计模式学习及其C语言实现笔记_第1页
第1页 / 共30页
设计模式学习及其C语言实现笔记_第2页
第2页 / 共30页
设计模式学习及其C语言实现笔记_第3页
第3页 / 共30页
设计模式学习及其C语言实现笔记_第4页
第4页 / 共30页
设计模式学习及其C语言实现笔记_第5页
第5页 / 共30页
点击查看更多>>
资源描述

《设计模式学习及其C语言实现笔记》由会员分享,可在线阅读,更多相关《设计模式学习及其C语言实现笔记(30页珍藏版)》请在金锄头文库上搜索。

1、设计模式学习及其 C 语言实现笔记第1章:面向对象 C语言(Object Oriented C )我曾经在嵌入式控制系统工作过,苦于嵌入式系统编程一直是C 语言,而没法用 C+ 或其他高级语言的面向对象方法编程。每次做项目,代码基本上都是重头再来,以前的代码有少量的可以 copy 过来直接用,开发和维护很不方便。偶然间发现 UML+OOPC 嵌入式 C 语言开发精讲里 面详细的讲述了 OOC 的原理和实现方法, 感觉不错。 遗憾的是上面只提供接口和多态的实现方法, 没有提供继承的处理。根据本人的研究,将其上面的宏文件进行修改和扩充,提出一种可行而且结 构明了的继承实现方法。至此, C 的 OO

2、 编程中的封装、继承、多态都全实现了。面向对象C语言(Object Oriented C )只是运用单纯的 C的宏(Macro)技巧,实现面向对象的基 本技术。借用 OOC.H 文件的宏,就可以实现类的封装、继承、多态。 OOC 毕竟不是一门语言, 不可能做出与 C+或C#这些面向对象语言一样的干练、简洁,有的甚至没法实现比如对private成员变量的限制等。但 OOC 方法借用宏在一定的规则下还是能做出比较漂亮的面向对象代码。下 面是对比 C+ 介绍 OOC.H 文件中的对象的命名、定义、封装等的规则。1 、类的封装和对象的构造1.1 类的封装(类的定义)在 C+ 中,类的定义如下class

3、 myClassprivate:int a;/- 类属性 (变量 )public:myClass();void Set(int a);void put();在 OOC 中“类”实际是结构体,myClass 定义的风格为CLASS(myClass)int a;void (*init)(void *t);void (*Set)(void *t,int a);void (*Put)(void *t);/- 类属性 (变量 )/- 初始化成员变量用函数/- 函数指针;在 C+ 和 OOC 的类封装中,最大的区别是 OOC 用函数指针来表示类的方法(或成员函数)此外 OOC 中没有 private 的变

4、量, private 变量只能通过定义方法来实现,比如把 int a 改写 为 int _a ,这样也许外面误访问的可能性大大降低,但还是不能阻止外面访问。1.2 类的成员函数的实现C+ 中可以在类内部定义成员函数的实现, 也可以在类的外面。 而 OOC 中的类实质是 struct , 其所存放的只能是变量,其中的函数指针变量是用来实现类的方法。因此在 OOC 的类中是不 能定义函数的实现的。 OOC 中函数也不像 C+ 中的函数属于哪个类就和哪个类紧密结合在一 起。00C中的函数的实现就是普通的函数实现,只是函数的参数要和CLASS0宏定义的函数(指针)的参数变量保持一致。例如myClass

5、类的Set方法可以取名 Set,也可以用别的名。如果在一个 .C 文件中,成员函数取名模式为: funName_ClassName(), 这样比较便于阅读和区分。按照该规则,则 myClass 的方法实现定义如下:void init_myClass(void *t) myClass *cthis = t;cthis-a = init_Number;/ 赋你想要赋给的初始值,也可以通过增加 init() 参数传进来void Set_myClass(void*t,int a) myClass *cthis = t;cthis-a = a;void Put _myClass(void*t) myCl

6、ass *cthis = t;printf( “ n this is myClass fun ” );这里和 C+ 不同的是,在 C+ 中,成员函数可以直接访问类的成员变量,而 OOC 中的成员 函数要访问成员变量,必须要有参数传递过来,因此, OOC 中凡是要访问其成员变量的必须要增 加一个 void*t 的参数。比如函数 Set() 在 C+ 只要有一个 int 参数就行了,在 OOC 中必须要带有 一个 void* 指针参数,通过该参数才能访问到 myClass 类的其他变量或者成员函数。1.3 对象的构造在 C+ 中,定义了一个对象的同时也调用了构造函数。在 OOC 中没有这样的功能,

7、 OOC 的 对象定义,实际上只是定义了个含有函数指针的结构体,要使得该结构体变成相当于 C+ 中的对 象,必须要对该对象 (结构体 )的成员变量进行初始化和方法(指针函数)与具体定义的函数进行关 联。在 C+ 中这两步一下就在定义对象时候自动调用构造函数现了, 而 OOC 中只能分两步走。因 标准此,在 myClass 定义中, C+ 没有 void init(void *t) 函数,而任何 OOC 定义的类必须要包含该 函数 (指针,接口和抽象类除外 ),否则无法对成员变量进行初始化。根据 OOC 中的宏,以 myClass 为例,对象的构造函数格式如下:CTOR(myClass)FUNC

8、TION_SETTING(init, init_myClass);FUNCTION_SETTING(Set, Set_myClass);FUNCTION_SETTING(Put, Put_myClass);END_CTOR 构造函数把对象中的函数指针和函数关联起来,调用函数指针就是对函数的调用。通过该构造 函数后, OOC 定义的对象才是一个真正意义上的对象,即函数指针有了函数的功能。1.4 、对象的实例化和规则定义好类后就要实例化,在 C+ 中, myClass 的对象定义为: myClass myObject ;其中已 经隐含了 myObject 对象的构造和成员变量的初始化。 在 OOC

9、 中,其定义和处理 3 步如下: myClass myObject ; / 1 、定义对象CLASS_CTOR(myClass ,myObject);/ 2 、构造对象使得函数指针和函数关联myObject.init(&myObject); / 3 、初始化对象的成员变量, 注意: & myObject (取 地址)至此,当个类的定义、封装、对象的构造和初始化就结束了。2、继承和接口的实现2.1 、继承和 C 实现public 和 protect 的成员变量和成员在 C+ 继承就是子类不需要重新定义拥有了其父类的函数。如果子类中重新定义了父类的方法, 如果父类该方法是虚函数, 则子类函数覆盖了

10、父类函数; 如果父类函数不是虚函数则为子类函数隐藏了父类函数。覆盖和隐藏的区别是:如果发生覆盖,当 父类指针指向子类对象时,通过指针调用同名虚函数,则执行子类的虚函数;如果发生隐藏,则调 用的是父类的同名函数。例如:class BaseApublic:BaseA()Virtual void Put()cout“ 调用 BaseA 的函数” endl;class BaseBpublic:BaseB()void Put()cout调用BaseB 的函数” endl;class ChildA : public BaseApublic:ChildA ()void Put()cout调用ChildA的函

11、数” endl;class ChildB : public BaseBpublic:ChildB ()void Put()cout“ 调用 ChildB 的函数” Put();/- 调用子类 ChildA 的 Put() 函数 ;BaseB *pb = new ChildB();pb-Put();/- 调用父类 BaseB 的 Put() 函数 ;输出结果是:调用 ChildA 的函数调用 BaseB 的函数在 OOC 中只是借用 C 的宏没法实现 C+ 这些复杂的机制,但能实现基本的继承,即拥有父 类的全部属性和方法。 OOC 中没有私有、保护属性的概念,所有父类属性和方法都是可见的。通 过

12、构造函数的处理,可以在 OOC 中实现隐藏和覆盖。下面是 OOC 中的隐藏和覆盖的讲解,在设 计模式中更多的是覆盖,而隐藏用到的比较少。2.2 、继承中覆盖和隐藏的实现为了方便解说,用 myClass 做基类,则定义子类 myChildA 的方法如下CLASS(myChildA)/- 本书 OOC 目前只研究单继承/- 表示继承 myClass 类, 必须放在最前面 EXTENDS(myClass);int data;void (*init)(void *t);void (*Put)(void*t);子类要注意的地方有 3 点:1、 被继承的类的宏说明 EXTENDS(baseClass) 必

13、须放在子类定义的最开头。2、 子类的 init() 函数里面必须要调用基类的 init() 函数,否则基类的属性没有初始化。3、 在构造子类的地方 CTOR(myChildA) 下最开头必须要增加调用基类构造的宏。myChildA 类的初始化函数定义如下:void init_ myChildA(void *t) myChildA *cthis = t;cthis- myClass .init ( &cthis-myClass ); / - 基 类 的 初 始 化 , 注 意 : &cthis-myClass/- 与基类的 init() 函数参数要一致cthis-data = yourNumbe

14、r;myChildA 虚函数覆盖的实现假定 myClass 类中 Put() 为虚函数,则子类必须定义自己 Put() 的实现, myChildA 自己重新 定义的 Put() 如下:void Put_ myChildA ()printf( “ this is myChildA fun 、n ” );于是在构造函数中,遵循 C+ 的原理,先对基类进行构造,然后对基类的虚函数重新绑定,具体处理代码如下CTOR(myChildA)BASE_CTOR( myClass );/- 调用基类构造函数实现对基类函数关联FUNCTION_SETTING( myClass.Put, Put_ myChildA

15、); / -Put() 的虚函数实现关联绑定FUNCTION_SETTING(init, init_ myChildA);FUNCTION_SETTING(Put, init_ myChildA);END_CTOR在 CTOR(myChildA) 中,通过重新设置子类内的 myChildA .Put 的关联函数,从而实现虚函数的 意义。如果要实现 C+ 中的隐藏功能,只要将 FUNCTION_SETTING( myChildA .Put, Put_ myChildA )去掉就是了,因为 BASE_CTOR( myClass ) 已经将 myClass.Put 与 Put_ myClass 关联了。实现 隐藏 的构造

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 医学/心理学 > 基础医学

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号