C语言实现OOP 版本2
写版本2的原因,还是发现在不同的具体图形模块里发现了重复的release代码,这是坏味道,所以还是决定消除这些重复代码,DRY!
shape.h
#ifndef SHAPE_H
#define SHAPE_H typedef struct shape_t
{
void *shapeData;
void (*area)(void *);
void (*release)(void *);
}Shape; void release(void *shape); #endif
shape.c
#include <stdlib.h>
#include "shape.h" void release(void *shape)
{
free(((Shape*)shape)->shapeData);
free(shape);
}
circle.h
#ifndef CIRCLE_H
#define CIRCLE_H typedef struct
{
double r;
}CircleData; typedef struct
{
void *shapeData;
void (*area)(void *);
void (*release)(void *);
}Circle; Circle *makeCircle(double r); #endif
circle.c
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "shape.h"
#include "circle.h" const double PI = 3.14159; static void area(void *shape)
{
Circle *_circle = (Circle *)shape;
CircleData* data = (CircleData*)_circle->shapeData;
printf("the circle area is %f \n", data->r * data->r * PI);
} /*
static void release(void *shape)
{
Circle *_circle = (Circle *)shape;
CircleData* data = (CircleData*)_circle->shapeData;
free(data);
free(_circle);
}
*/ Circle *makeCircle(double r)
{
CircleData* circleData = (CircleData*)malloc(sizeof(CircleData));
Circle* circle = (Circle*)malloc(sizeof(Circle));
assert(circleData != NULL);
assert(circle != NULL);
assert(r > ); circleData->r = r;
circle->shapeData = circleData;
circle->area = &area;
circle->release = &release; return circle;
}
square.h
#ifndef SQUARE_H
#define SQUARE_H typedef struct
{
double x;
double y;
}SquareData; typedef struct
{
void *shapeData;
void (*area)(void *);
void (*release)(void *);
}Square; Square *makeSquare(double x, double y); #endif
square.c
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "shape.h"
#include "square.h" static void area(void *shape)
{
Square *square = (Square *)shape;
SquareData* data = (SquareData*)square->shapeData;
printf("the square area is %f \n", data->x * data->y);
} /*
static void release(void *shape)
{
Square *square = (Square *)shape;
SquareData* data = (SquareData*)square->shapeData;
free(data);
free(square);
}
*/ Square *makeSquare(double x, double y)
{
SquareData* squareData = (SquareData*)malloc(sizeof(SquareData));
Square* square = (Square*)malloc(sizeof(Square));
assert(squareData != NULL);
assert(square != NULL);
assert(x > && y > ); squareData->x = x;
squareData->y = y;
square->shapeData = squareData;
square->area = &area;
square->release = &release; return square;
}
main.c 发现没有,尽管内部进行了调整,这些的代码丝毫没变!重构就应该这样,内部的调整不太涉及到client代码,除非真的决定修改接口,修改接口内部应该优先于调整接口
#include <stdio.h>
#include "shape.h"
#include "circle.h"
#include "square.h" void printShapeArea(Shape **shape,int length)
{
int i=;
for(i=;i<length;i++)
{
shape[i]->area(shape[i]);
shape[i]->release(shape[i]);
}
} int main()
{
Shape *p[] = {(Shape*)makeCircle(3.2),(Shape*)makeCircle(3.2),(Shape*)makeSquare(3.1,)};
printShapeArea(p,);
return ;
}
C语言实现OOP 版本2的更多相关文章
- C语言实现OOP 版本3 :简化代码
我倒是不追求代码和C++相似,但是应该追求简洁的代码,下面是一个新的尝试 shape.h #ifndef SHAPE_H #define SHAPE_H typedef struct shape_t ...
- 一个UUID生成算法的C语言实现 --- WIN32版本 .
一个UUID生成算法的C语言实现——WIN32版本 cheungmine 2007-9-16 根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...
- C# 语言规范_版本5.0 (第2章 词法结构)
1. 词法结构 1.1 程序 C# 程序 (program) 由一个或多个源文件 (source file) 组成,源文件的正式名称是编译单元 (compilation unit)(第 9.1 节). ...
- 几种不同程序语言的HMM版本
几种不同程序语言的HMM版本 “纸上得来终觉浅,绝知此事要躬行”,在继续翻译<HMM学习最佳范例>之前,这里先补充几个不同程序语言实现的HMM版本,主要参考了维基百科.读者有兴趣的话可以研 ...
- 一个UUID生成算法的C语言实现——WIN32版本
源: 一个UUID生成算法的C语言实现——WIN32版本
- C语言的OOP实践(OOC)
OOC 面向对象 C 语言编程实践 - 文章 - 伯乐在线http://blog.jobbole.com/105105/ ---硬着头皮看完了,但是感觉还是抽象有不理解的地方,感觉用C实现OOP好难啊 ...
- C# 语言规范_版本5.0 (第10章 类)
1. 类 类是一种数据结构,它可以包含数据成员(常量和字段).函数成员(方法.属性.事件.索引器.运算符.实例构造函数.静态构造函数和析构函数)以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类 ...
- C# 语言规范_版本5.0 (第8章 语句)
1. 语句 C# 提供各种语句.使用过 C 和 C++ 编程的开发人员熟悉其中大多数语句. statement: labeled-statement declaration-statement emb ...
- C# 语言规范_版本5.0 (第7章 表达式)
1. 表达式 表达式是一个运算符和操作数的序列.本章定义语法.操作数和运算符的计算顺序以及表达式的含义. 1.1 表达式的分类 一个表达式可归类为下列类别之一: 值.每个值都有关联的类型. 变量.每个 ...
随机推荐
- chinaunix:腾讯面试题
腾讯电商面试回来,发现我太菜了,缺乏技术深度. 笔试题感觉不难,但是做了之后总是发觉少点什么东西,深度!这是这场面试总结出来的. 凭记忆分享下笔试,面试题.大家一起解决,然后分享下该看什么书,可以解决 ...
- Ubuntu12.04 下修改Apache端口号
1:$sudo vim /etc/apache2/ports.conf NameVirtualHost *:80Listen 8090 #将此行的80修改成8090 2:sudo vim /etc/a ...
- Unity3D中C#编写脚本
1.继承MonoBehaviour类:任何一个游戏脚本都需要去继承MonoBehaviour这个类,只是在创建javascript脚本的时候,系统会将其类名与继承关系隐藏起来. 2.声明变量:使用Ja ...
- C#反射 获取程序集信息和通过类名创建类实例(转载)
C#反射获取程序集信息和通过类名创建类实例 . System.Reflection 命名空间:包含通过检查托管代码中程序集.模块.成员.参数和其他实体的元数据来检索其相关信息的类型. Assembly ...
- TextWatcher编辑框监听器
TextWatcher tw = new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int sta ...
- zabbix 添加自定义key
vim /etc/zabbix/zabbix_agentd.conf UserParameter=zjzc.login,/bin/sh /usr/sbin/get_login.sh UserParam ...
- 利用Visual Studio寻找C#程序必要的运行库文件
在工程打包中,有时候很头痛的就是运行所需要的库文件不能够全面的包含进来,特别是有时候调用了一系列外部扩展.对于这些问题,我们可以借用Visual Studio的打包功能帮助我们寻找软件运行必须的库文件 ...
- APP制作过程
直播App开发的过程 第一步:分解直播App的功能,我们以X客为例 视频直播功能,这是一款直播App最主要的功能,要能支持视频直播RTMP推流,使画面传输流畅.清晰(美颜后的清晰,你懂的聊天功能,用户 ...
- Filter过滤器实现登录检查
主要利用filter过滤掉未经登录而直接跳转到非登录访问页面.代码而言的话并不难,只是有几点问题需要注意一下. 1.使用filter需要配置web.xml,如果是/*那么在拦截后的页面会连带jsp页面 ...
- (转)sql中 in 、not in 、exists、not exists 用法和差别
exists (sql 返回结果集为真) not exists (sql 不返回结果集为真) 如下: 表A ID NAME 1 A1 2 A2 3 A3 表B ID AI ...