写版本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的更多相关文章

  1. C语言实现OOP 版本3 :简化代码

    我倒是不追求代码和C++相似,但是应该追求简洁的代码,下面是一个新的尝试 shape.h #ifndef SHAPE_H #define SHAPE_H typedef struct shape_t ...

  2. 一个UUID生成算法的C语言实现 --- WIN32版本 .

    一个UUID生成算法的C语言实现——WIN32版本   cheungmine 2007-9-16   根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...

  3. C# 语言规范_版本5.0 (第2章 词法结构)

    1. 词法结构 1.1 程序 C# 程序 (program) 由一个或多个源文件 (source file) 组成,源文件的正式名称是编译单元 (compilation unit)(第 9.1 节). ...

  4. 几种不同程序语言的HMM版本

    几种不同程序语言的HMM版本 “纸上得来终觉浅,绝知此事要躬行”,在继续翻译<HMM学习最佳范例>之前,这里先补充几个不同程序语言实现的HMM版本,主要参考了维基百科.读者有兴趣的话可以研 ...

  5. 一个UUID生成算法的C语言实现——WIN32版本

    源: 一个UUID生成算法的C语言实现——WIN32版本

  6. C语言的OOP实践(OOC)

    OOC 面向对象 C 语言编程实践 - 文章 - 伯乐在线http://blog.jobbole.com/105105/ ---硬着头皮看完了,但是感觉还是抽象有不理解的地方,感觉用C实现OOP好难啊 ...

  7. C# 语言规范_版本5.0 (第10章 类)

    1. 类 类是一种数据结构,它可以包含数据成员(常量和字段).函数成员(方法.属性.事件.索引器.运算符.实例构造函数.静态构造函数和析构函数)以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类 ...

  8. C# 语言规范_版本5.0 (第8章 语句)

    1. 语句 C# 提供各种语句.使用过 C 和 C++ 编程的开发人员熟悉其中大多数语句. statement: labeled-statement declaration-statement emb ...

  9. C# 语言规范_版本5.0 (第7章 表达式)

    1. 表达式 表达式是一个运算符和操作数的序列.本章定义语法.操作数和运算符的计算顺序以及表达式的含义. 1.1 表达式的分类 一个表达式可归类为下列类别之一: 值.每个值都有关联的类型. 变量.每个 ...

随机推荐

  1. Portal技术介绍

      Portal技术介绍 Portal是web应用发展的一个重要趋势,目前几乎所有大的软件厂商都有自己的Portal产品.并且Portal技术已经形成规范.本文对Portal技术和产品进行了分析,目的 ...

  2. Ant构建与部署Java项目---入门

    原文地址:http://tech.it168.com/j/2007-11-09/200711091344781.shtml Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建 ...

  3. Codeforces 543D Road Improvement

    http://codeforces.com/contest/543/problem/D 题意: 给定n个点的树 问: 一开始全是黑边,对于以i为根时,把树边白染色,使得任意点走到根的路径上不超过一条黑 ...

  4. perl 登录某网站

    <pre name="code" class="html">use Net::SMTP; use LWP::UserAgent; use HTTP: ...

  5. openwrt l7过滤qos配置

    openwrt l7过滤qos配置     电梯直达 1# 本帖最后由 木鸟 于 2010-7-27 10:22 编辑 openwrt的qos基于hsfc.提供了分类标记,流量控制等功能,可能还有整形 ...

  6. 【剑指offer】面试题39扩展:平衡二叉树

    题目: 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 思路: 直观的思路是,判断根结点的左子树.右子树高度差是否小于1. 为避免多次访问同一结点,应该用后序遍历的方式访问. 注意:加号优先级高于条件 ...

  7. c语言二维数组变色龙之死字的打印

    1 #include <stdio.h> #include <stdlib.h> void main() { ][]= { {'#','#','#',' ','#','#',' ...

  8. css中的7中属性选择器

    在CSS的选择符中有七个属性选择符.它们分别是: 1.E[att] 选择具有att属性的E元素. 2.E[att="val"] 选择具有att属性且属性值等于val的E元素. 3. ...

  9. 万恶DevExpress

    公司需要,开始了DevExpress的学习之旅,说它万恶也只是在不了解它的情况下,熟悉之后能很方便的实现很多想要的功能 这里简单写一下要整理的内容,也就是大纲,以后再慢慢添加 一.控件和组件 date ...

  10. HDU2206 IP的计算 【经典题】

    IP的计算 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...