一. 问题

在面向对象系统的分析与设计过程中经常会遇到这样一种情况:对于某一个业务逻辑(算法实现)在不同的对象中有不同的细节实现,但是逻辑(算法)的框架(或通用的应用算法)是相同的。Template提供了这种情况的一个实现框架。

二. 模式

Template 模式是采用继承的方式实现这一点:将逻辑(算法)框架放在抽象基类中,并定义好细节的接口,子类中实现细节。

三. 代码

abstractClass.h

#ifndef ABSTRACTCLASS_H

#define ABSTRACTCLASS_H

#include

#include

typedef struct {

size_t size;

void* (*ctor)(void *_self, va_list *params);

void* (*dtor)(void *_self);

void (*templateMethod)(const void *_self);

char *description;

} AbstractClass;

#endif

concreteClass1.h

#ifndef CONCRETECLASS1_H

#define CONCRETECLASS1_H

#include "abstractClass.h"

typedef struct {

const void *abstractClass;

void (*primitiveOperation1)(const void *_self);

void (*primitiveOperation2)(const void *_self);

int a;

} _ConcreteClass1;

extern const void *ConcreteClass1;

#endif

concreteClass1.c

#include "concreteClass1.h"

#include

#include

#include

#include

#include

static void *concreteClass1Ctor(void *_self, va_list *params) {

_ConcreteClass1 *self = _self;

const char *description = va_arg(*params, const char *);

(*(AbstractClass **)self)->description = calloc(1, strlen(description) + 1);

assert((*(AbstractClass **)self)->description);

strncpy((*(AbstractClass **)self)->description, description, strlen(description) + 1);

self->a = va_arg(*params, int);

return self;

}

static void *concreteClass1Dtor(void *_self) {

_ConcreteClass1 *self = _self;

if (NULL != (*(AbstractClass **)self)->description) {

free((*(AbstractClass **)self)->description);

(*(AbstractClass **)self)->description = NULL;

}

self->a = 0;

return self;

}

static void concreteClass1PrimitiveOperation1(const void *_self) {

if (NULL != (*(const AbstractClass * const *)_self)->description) {

fprintf(stdout, "%s\n", (*(const AbstractClass * const *)_self)->description);

}

}

static void concreteClass1PrimitiveOperation2(const void *_self) {

const _ConcreteClass1 *self = _self;

fprintf(stdout, "%d\n", self->a);

}

static void concreteClass1TemplateMethod(const void* _self) {

concreteClass1PrimitiveOperation1(_self);

concreteClass1PrimitiveOperation2(_self);

}

static AbstractClass _concreteClass1 = {

sizeof(_ConcreteClass1),

concreteClass1Ctor,

concreteClass1Dtor,

concreteClass1TemplateMethod,

NULL

};

const void *ConcreteClass1 = &_concreteClass1;

concreteClass2.h

#ifndef CONCRETECLASS2_H

#define CONCRETECLASS2_H

#include "abstractClass.h"

typedef struct {

const void *abstractClass;

void (*primitiveOperation1)(const void *_self);

void (*primitiveOperation2)(const void *_self);

double b;

} _ConcreteClass2;

extern const void *ConcreteClass2;

#endif

concreteClass2.c

#include "concreteClass2.h"

#include

#include

#include

#include

#include

static void *concreteClass2Ctor(void *_self, va_list *params) {

_ConcreteClass2 *self = _self;

const char *description = va_arg(*params, const char *);

(*(AbstractClass **)self)->description = calloc(1, strlen(description) + 1);

assert((*(AbstractClass **)self)->description);

strncpy((*(AbstractClass **)self)->description, description, strlen(description) + 1);

self->b = va_arg(*params, double);

return self;

}

static void *concreteClass2Dtor(void *_self) {

_ConcreteClass2 *self = _self;

if (NULL != (*(AbstractClass **)self)->description) {

free((*(AbstractClass **)self)->description);

(*(AbstractClass **)self)->description = NULL;

}

self->b = 0;

return self;

}

static void concreteClass2PrimitiveOperation1(const void *_self) {

if (NULL != (*(const AbstractClass * const *)_self)->description) {

fprintf(stdout, "%s\n", (*(const AbstractClass **)_self)->description);

}

}

static void concreteClass2PrimitiveOperation2(const void *_self) {

const _ConcreteClass2 *self = _self;

fprintf(stdout, "%f\n", self->b);

}

static void concreteClass2TemplateMethod(const void* _self) {

concreteClass2PrimitiveOperation1(_self);

concreteClass2PrimitiveOperation2(_self);

}

static AbstractClass _concreteClass2 = {

sizeof(_ConcreteClass2),

concreteClass2Ctor,

concreteClass2Dtor,

concreteClass2TemplateMethod,

NULL

};

const void *ConcreteClass2 = &_concreteClass2;

new.h

#ifndef __NEW_H__

#define __NEW_H__

void *New(const void *_class, ...);

void Delete(void *_class);

void TemplateMethod(const void *_class);

#endif

new.c

#include "new.h"

#include "abstractClass.h"

#include

#include

#include

#include

void *New(const void *_class, ...) {

const AbstractClass *class = _class;

void *p = calloc(1, class->size);

assert(p);

*(const AbstractClass **)p = class;

if (class->ctor) {

va_list params;

va_start(params, _class);

p = class->ctor(p, ¶ms);

va_end(params);

}

return p;

}

void Delete(void *_class) {

const AbstractClass **class = _class;

if (_class && *class && (*class)->dtor) {

_class = (*class)->dtor(_class);

}

free(_class);

}

void TemplateMethod(const void *_class) {

const AbstractClass * const *class = _class;

if (_class && *class && (*class)->templateMethod) {

(*class)->templateMethod(_class);

}

}

main.c

#include "new.h"

#include "concreteClass1.h"

#include "concreteClass2.h"

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

void *p1 = New(ConcreteClass1, "ConcreteClass1", 10);

void *p2 = New(ConcreteClass2, "ConcreteClass2", 20.1);

TemplateMethod(p1);

TemplateMethod(p2);

Delete(p1);

Delete(p2);

return 0;

}

图片来源:http://blog.csdn.net/hmsiwtv/article/details/9627019

c语言模板程序,模板模式 (C语言实现)相关推荐

  1. c语言笔试程序改错题,C语言笔试--程序改错题.doc

    C语言笔试--程序改错题 铜尖刮佛烁休凹汝宰或贷呵茎丑傅汞访沾犹扯视自女垂桶癌苞详阴疾澜赏斑萝厩蕴莽钢邹叶疹单樊捣前烬吊崖匝企送跃赫鳃投媳暴棺蹲后牡膊谗甲柜侍叠磐燥陷懦昧颈芝矢肪灌就冷沽梗挑评保崎士羡 ...

  2. 用c语言运行程序的优点,C语言学习与总结---第一章:C语言概述

    第一章:C语言概述 1.绪论 2.计算机程序 3.计算机语言 4.C语言的发展及其特点 5.最简单的C语言程序 6.运行C语言程序的方法与步骤 7.程序设计任务 1.绪论 C语言是计算机基础语言,本次 ...

  3. c语言报告程序分析报告,2012C语言程序分析报告.doc

    2012C语言程序分析报告 C语言程序设计专周 专 周 报 告 班级:10611 学号:20 姓名: 设计时间:2011-5-30至2011-6-3 一.设计题目:职工工资管理小软件 二.实习目的 1 ...

  4. c语言经典程序100txt例,C语言经典程序100例txt格式.doc

    C语言经典程序100例txt格式 C语言经典程序100例txt格式 C语言经典程序100例txt格式.txt人永远不知道谁哪次不经意的跟你说了再见之后就真的再也不见了.一分钟有多长?这要看你是蹲在厕所 ...

  5. C语言C程序的构成,C语言程序的构成.doc

    C语言程序的构成 C语言程序的构成 章 C语言程序的构成 与C++.Java相比,C语言其实很简单,但却非常重要.因为它是C++.Java的基础. 不把C语言基础打扎实,很难成为程序员高手. 一.C语 ...

  6. c语言循环程序模板,循环结构程序设计C语言程序

    循环结构程序设计C语言程序Tag内容描述: 1.第5章 循环结构程序设计,C 语言程序设计,北京航空航天大学 交通科学与工程学院 徐国艳,2019/7/12,2,循环的基本概念 不同形式的循环控制 多 ...

  7. c语言设置程序自动执行,c语言如何设置程序进程执行优先权

    c语言如何设置程序进程执行优先权 使用setpriority()函数设置程序进程执行优先权: 头文件: #include#include 定义函数: int setpriority(int which ...

  8. 如何写一个能被手机打开的C语言小程序,如何用C语言中一些简单的语句做一个小程序,能够输入一个字符就会弹出一句话...

    满意答案 lyj1260 2015.03.28 采纳率:43%    等级:11 已帮助:6408人 这个不难,是最基本的C语言程序了,我写个示例给你 #include //包含头 int main( ...

  9. 模仿下列程序自己打印一个趣味图案c语言,趣味程序导学C语言(28页)-原创力文档...

    C 趣味程序导学 语言 (请到附件里下载源代码与课件) 电脑游戏,一个熟悉而诱人的字眼,常常不经意地浮现在我们的脑海当中. 有梦幻神奇的 <传奇>,有惊险刺激的 <反恐精英>, ...

最新文章

  1. PIE SDK影像快速拼接
  2. element-ui表格列金额显示两位小数
  3. posix多线程有感--线程高级编程(条件变量)
  4. Redis实战(三):Redis的List、Set、Hash、sorted_set、skip list
  5. matlab 中max函数用法
  6. 2019牛客多校Monotonic Matrix
  7. [Silverlight]奇技银巧系列-2
  8. PAT 1017 Queueing at Bank[一般]
  9. python 类初始化参数校验_python之类的任意数量参数初始化
  10. pip install -q git+https://github.com/tensorflow/docs.git报错
  11. 如果同时需要两张表,但其中一个表中没有另一个表中的字段,该如何正确使用
  12. Java常见算法之二分法查找算法详解
  13. Xmind思维导图 常用快捷键使用
  14. git is outside repository
  15. 微信H5页面分享案例模版
  16. 五问补盲(四)| 好用的补盲激光雷达,得满足哪些条件?
  17. Python实例6: 贺卡制作
  18. oracle简单查询语句
  19. 量化交易 第二课 平台介绍
  20. Win10 360浏览器打不开特定网站网页,选择兼容模式有时可以,不稳定

热门文章

  1. Vuejs-踩坑/注意事项记录
  2. Android手机摇一摇的实现SensorEventListener
  3. Linux 7 cmake:curses library not found
  4. Flask的session使用
  5. 前端、数据库、Django简单的练习
  6. IDEA远程调试服务器代码
  7. iPhone开发【一】从HelloWorld開始
  8. 【学习笔记】Node.js学习笔记(二)
  9. windows下的C/C++精确计时
  10. 按键中断异步通知实现