http://my.oschina.net/fzyz999/blog/138491
关于本文
本文是笔者在阅读《C++沉思录》第0章——序幕后的一点想法,可以算作是笔记也可以算作是读后感。参加了这么多年NOIP,一直在使用C++ 语言,但由于平时写的代码都是100~300行的短代码,所以完全无法理解C++的类的意义。今日阅读Andrew Koenig大师的这部作品,虽然只阅读了寥寥数言,但对于类的理解顿时加深了许多。
正文
让我们先假设一个情景。一位客户提出这样一个需求:编写一个程序输出Hello World!到屏幕。这个需求非常简单,任何一个学过一点C语言的人都可以迅速实现:
6 |
printf("Hello World!"); |
但如果用C++的类来写,就要复杂得多。
16 |
output.print("Hello World"); |
显而易见的是,C++的版本要复杂得多,那么,我们为什么要用C++?C++的优势何在?我们继续改动我们的程序。接下来,假设客户又增加了需 求,希望能输出多个字符串。于是,我们可以建立多个Output类型的变量,以适应需求变动。而C语言代码可以通过多个printf函数解决这次需求变 动。
然后,客户目前的需求又有所改变:客户要求设计一个开关,可以控制是否输出字符串。针对这个需求变动,我们可以写出这样的C++代码:
12 |
void setState(bool enabled) |
18 |
//If true, then output is enabled. |
19 |
//Otherwise, output is disabled. |
25 |
output.setState(true); |
26 |
output.print("Hello World"); |
这样,所有的Output就都具有了开关。而C语言代码就需要一个相对规模较大的重构才可以应对这个变动的需求。
从上面那个例子我们可以看出,同样的功能,无论是C还是C++往往都有能力去实现。不同点在于可维护性。前面的代码不断被修改的直接原因就在于需求变化。需求的不断变化才是问题的关键。 如果代码是一次性的,针对某一特定问题的,不会变化的,那么怎样实现都可以。在这方面很难体现出类的优势。这也是为什么写了这么多年的NOIP的题目,笔 者依旧难以深入理解类。题目是死的,没有需求上的变动。但大型软件不一样,它会随着时间的发展而发展,随着新需求的出现而不断变化。而且越大型的软件遇到 一次需求变动时,需要改动的代码可能就越多。而C++类便是针对这一问题的一种解决方案。有了类的抽象,需求的变动对代码的影响就减小了很多。这样,软件 的维护成本就被大规模地降低了。
总而言之,C++的类是为了解决软件开发中不断的需求变化而生的。在必要的时候抽象具体的细节,以减小变化对代码造成的影响。这就是类的作用。
后记
C++总被人认为是最难以精通的语言。它提供了大量特性,类、模板等等。但同时,它也保留了C语言的面向过程。它犹如一把瑞士军刀,提供了大量 的功能,是解决问题的利器。但同时,它也信任程序员能够恰当地选用合适的工具(瑞士军刀提供了很多工具)。根据具体的需求和可能的需求变动谨慎使用它,才 是正确的做法。例如在NOIP这类的程序中就不使用复杂的抽象,因为题目是死的,几乎没有需求变动。速度才是关键。一些功能清晰的小工具也不必使用太过复 杂的抽象,否则就是过度设计了。为不可能的变化而设计,也会增加软件开发的成本。而对于那些在可预见的时间内规模会迅速增长的程序,抽象就十分有必要了。 根据可预见的需求,使用恰当的程序语言表达,才是正确的。
综上所述,我的思路好像还是不太清晰。[joke:)]
- 最近使用Nginx的一点新得
1.基本的负载配置 Nginx最简单的配置模块如下 upstream name{ server ip:port; server ip:port; } server { listen 80; serve ...
- python 中的一点新知识
逻辑行与物理行 所谓物理行(Physical Line)是你在编写程序时 你所看到 的内容.所谓逻辑行(Logical Line)是 Python 所看到 的单个语句.Python 会假定每一 物理行 ...
- 工控PLC中,关于定时器TON,TOF,的一点新认知,或者说醒悟吧!
PLC 中的定时器,都是放在一个具体PRG任务单元中的,而PRG单元需要放在具体固定的周期循环任务中才能被执行,而这个周期循环任务的循环周期 T: 与定时器的定时时间T0: T与T0 的数量级 ...
- 译|调整JavaScript抽象的迭代方案
原文作者:Kaloyan Kosev 原文链接:https://css-tricks.com/adapting-javascript-abstractions-time/ 翻译译者:小溪里 校对:华翔 ...
- 调整JavaScript抽象的迭代方案
原文链接:Adapting JavaScript Abstractions Over Time 译者:小溪里 校对者:郭华翔.苗冬青 即使还没有读过我的文章<在处理网络数据的 JavaScrip ...
- C++默认构造函数的一点说明
大多数C++书籍都说在我们没有自己定义构造函数的时候,编译器会自动生成默认构造函数.其实这句话我一直也是 深信不疑.但是最近看了一些资料让我有了一点新的认识. 其实我觉得大多数C++书籍之所以这样描述 ...
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- Java-马士兵设计模式学习笔记-工厂模式-抽象工厂模式
一.概述 1.抽象工厂:当情况是需要产生一系列产品,若需更换产品,则要求一系列产品一起换,且要控制一系列产品的产生过程,此时可考虑抽象工厂模式.例:小明装修屋子,把电视.冰箱都替换掉,他这次需要把电视 ...
- .NET项目开发—浅谈面向接口编程、可测试性、单元测试、迭代重构(项目小结)
阅读目录: 1.开篇介绍 2.迭代测试.重构(强制性面向接口编程,要求代码具有可测试性) 2.1.面向接口编程的两个设计误区 2.1.1.接口的依赖倒置 2.1.2.接口对实体的抽象 2.2.迭代单元 ...
随机推荐
- struts2拦截器的实现原理
拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ...
- thinkphp中关于rbac的两个session
最近在做单点登录,需要session由sso的client生成.所以研究了下RBAC的类的代码. 有了这两个seesion就可以用rbac进行权限验证 $_SESSION[C('ADMIN_AUTH_ ...
- YII中URL地址美化
URL地址美化:urlManager地址管理(通过程序来实现url的地址美化) 例如: 原地址:http://localhost/项目/app/index.php?r=控制器/方法 新地址:http: ...
- yii中的自定义组件
yii中的自定义组件(组件就是一些自定义的公用类) 1.在项目目录中的protected/components/Xxxx.php 2.在Xxxx.php中定义一个类,类名必须与文件名相同 3.控制器中 ...
- 你不知道的javascript 上卷 读书笔记
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- java List交集 并集 差集 去重复并集
首先定义两个list List list1 =new ArrayList(); list1.add("); list1.add("); list1.add("); Lis ...
- 百度编辑器1.4.3 .net版在vs2008的使用方法
由于在官方下载的ueditor包是在vs2012下开发的,可以在vs2010中使用,但在vs2008中就会报错.折腾了一翻,现将解决方法分享给需要的朋友,其实就是把里面包含.net4.0的元素换成.n ...
- HTML表单元素中disabled的元素的值不会提交到服务器
一.在HTMl页面的form表单中对disabled的元素的属性和值不会提交到服务器 实例1: <form action="#"> <input type=&qu ...
- A swift Tour
传统的认为,一个新的语言的第一个应用程序都会打印"Hellow,Word",在Swift中,可以只需要一行代码: pringln("Hello, word") ...
- 零基础Visual Fox Pro 6.0自学笔记(VFP6.0图文教程)
序:有个哥们读大一,学的金融,由于考试需要去学VFP.拜托我帮忙找教程,发觉网上没有合适的,教学视频多半要收费,优秀文档很少.微软官方也不重视VFP了,真可惜.遂生出写一个入门教程的想法.图文并茂的可 ...