在学数据结构的时候,我常有这样目标——写出能够最大程度复用的代码(算法正确,封装优秀)。我常想——如何能在短时间内达成“算法正确,封装优秀”这样的目标。经过一段时间的摸索,我的结论是:先用C写出正确的算法,再将它改写成C++ class,最后再考虑改为template。这种方法简单可行,基本实现了 逻辑(算法)设计与接口设计两个步骤的分离。

在写数据结构代码的场景下,使用这种方法的前提是——你必须先把这个数据结构需要哪些操作弄清楚,并且有如何实现的大致思路(如果不清楚,翻翻书☺)。

下面以一个有界队列为例,进行演示。

正确的算法

在考虑如何实现算法时,可以完全不用任何封装(C struct的封装也不用),只要实现最小操作集合就行了,但测试必须要写。
这里就是实现所谓的“环形缓冲”,空出一个用于区分队满和队空。连同测试,代码如下:
(运行结果不在此贴出,感兴趣的同学自己运行)
在只考虑算法不考虑接口的情况下,写出这样的代码很容易(相信有点语言功底的都能写得出来)。当然,上面的#define TEST可以不写,用编译选项定义也是可以的。

封装为class

有了这样的基础,封装为C++ class就很容易了(这里直接包裹,实际情形可能有功能类似但参数不同的接口,略作封装即可)。这么简单的成员函数,没有必要分开来了,这里就用一个.h:

封装为类之后,测试代码有必要分开来写:


重构为class template

显然,这样直接封装的有界队列存在问题——元素类型固定(这通常是写成template的理由),缓冲大小固定。对于第一点,可以通过将代码重构为C++的类模板实现;即将元素的类型作为类模板的一个参数。对于第二点,也可以借助模板参数实现(模板除了有类型参数,也可以有值参数)。当然也可以把buffer改为指针,在ctor传入大小,这里不做介绍。代码如下:

此时的测试代码:

这里描述的方法(C->OO->template)主要是从代码复用的角度考虑,并非与传统OOP教材上的“先接口后实现”相违背。你可以理解为——如何让《数据结构》教材上的C代码的到最大程度上的复用。(多数《数据》教材采用C代码讲解,当然也有使用其他语言的)
直接使用“先接口,后实现”的方法,并非不行,只是可能要多改很多次代码(尤其是考虑模板的时候T^T,想想都是泪,不能让学弟学妹们掉同样的坑了)。使用本文所述方法的好处就是——可以让逻辑设计与接口设计两个过程解耦。

C++代码重构——从C global到C++ template的更多相关文章

  1. 让代码重构渐行渐远系列(3)——string.Equals取代直接比较与非比较

    重构背景及原因 最近由于项目组的人员在不断扩充,导致项目中代码风格各异,大有百花齐放甚至怒放之势.考虑到团队的生存与发展,经过众人多次舌战之后,最终决定项目组根据业务分成几个小分队,以加强团队管理与提 ...

  2. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十二) 代码重构使用反射工厂解耦(一)缓存切换

    前言 上一篇中,我们用了反射工厂来解除BLL和UI层耦合的问题.当然那是最简单的解决方法,再复杂一点的程序可能思路相同,但是在编程细节中需要考虑的就更多了,比如今天我在重构过程中遇到的问题.也是接下来 ...

  3. CSS代码重构与优化之路

    作者:@狼狼的蓝胖子 网址:http://www.cnblogs.com/lrzw32/p/5100745.html 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多, ...

  4. NET代码重构

    记一次.NET代码重构   好久没写代码了,终于好不容易接到了开发任务,一看时间还挺充足的,我就慢慢整吧,若是遇上赶进度,基本上直接是功能优先,完全不考虑设计.你可以认为我完全没有追求,当身后有鞭子使 ...

  5. 代码重构 & 常用设计模式

    代码重构 重构目的 相同的代码最好只出现一次 主次方法 主方法 只包含实现完整逻辑的子方法 思维清楚,便于阅读 次方法 实现具体逻辑功能 测试通过后,后续几乎不用维护 重构的步骤 1  新建一个方法 ...

  6. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十一) 代码重构使用反射工厂解耦

    前言 自从此博客发表以及代码开源以来,得到了许多人的关注.也没许多吧,反正在我意料之外的.包括几位大牛帮我做订阅号推广,真的很感谢他们.另外,还有几个高手给我提了一些架构上的问题.其实本身这个项目是没 ...

  7. CSS代码重构

    CSS代码重构的目的 我们写CSS代码时,不仅仅只是完成页面设计的效果,还应该让CSS代码易于管理,维护.我们对CSS代码重构主要有两个目的:1.提高代码性能2.提高代码的可维护性 提高代码性能 提高 ...

  8. 多线程的练习----妖,等待唤醒,代码重构,lock到condition

    × 目录 [1]需求 [2]妖的出现和解决 [3]等待唤醒 [4]代码重构 [5]改成Lock Condition ------------------------------------- 1,需求 ...

  9. 推荐五款优秀的PHP代码重构工具

    在软件工程学里,重构代码一词通常是指在不改变代码的外部行为情况下而修改源代码.软件重构需要借助工具完成,而重构工具能够修改代码同时修改所有引用该代码的地方.本文收集了五款出色的PHP代码重构工具,以帮 ...

随机推荐

  1. js和jquery如何获取图片真实的宽度和高度

    按照插入的图片的尺寸来判断图片是横图还是竖图.然后判断过后给予不同的展示方式,下面为大家介绍下js和jquery如何获取图片真实的宽度和高度   1.什么时候需要获取图片真实的宽度和高度 在做pc网页 ...

  2. 【JavaScript】[bind,call,apply] (function cal(){}());声明函数立即执行

    ---恢复内容开始--- 1.js 里函数调用有 4 种模式:方法调用.正常函数调用.构造器函数调用.apply/call 调用.同时,无论哪种函数调用除了你声明时定义的形参外,还会自动添加 2 个形 ...

  3. logback 配置详解

    一:根节点<configuration>包含的属性: scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true. scanPeriod: 设置监测配置文 ...

  4. IE下a标签后面的span元素向右浮动后错位

    错误原因span放在了a标签之后 正确写法是放在之前 如下: <li><span>2016-07-29</span><a href="#" ...

  5. JS点击更换网页背景颜色

    JS部分 <script type="text/javascript"> // 定义可换的颜色 var colors = ["#ff0000", & ...

  6. java-生成印章swing

    案例1 package com; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Font; import j ...

  7. 正则表达式 match 和 exec 比较

    match 和 exec 主要有两点不同: 1.exec是正则表达式的方法,而不是字符串的方法,它的参数才是字符串,如下所示: var re=new RegExp(/\d/); re.exec( &q ...

  8. 监控阮一峰老师的blog

    引言 阮一峰大家基本都认识,很厉害的一个人,经济学博士,文章写得很棒,知识面很广泛,计算机.算法.英语.文采,这是能想到的他的一些标签,他的博客应该算是最受欢迎的博客之一了. 我经常回去看他的博客,但 ...

  9. TypeScript Generics(泛型)

    软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用.支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性. 在C#和 ...

  10. BZOJ3771: Triple

    额我不是来发题解的,只是非常郁闷= =,这题的答案最大是1.2e9/6左右,所以用ntt的话要在模意义下除以6,不能最后除,否则刚好爆掉= = #include<bits/stdc++.h> ...