http://my.oschina.net/fzyz999/blog/138491

关于本文

  本文是笔者在阅读《C++沉思录》第0章——序幕后的一点想法,可以算作是笔记也可以算作是读后感。参加了这么多年NOIP,一直在使用C++ 语言,但由于平时写的代码都是100~300行的短代码,所以完全无法理解C++的类的意义。今日阅读Andrew Koenig大师的这部作品,虽然只阅读了寥寥数言,但对于类的理解顿时加深了许多。

正文

  让我们先假设一个情景。一位客户提出这样一个需求:编写一个程序输出Hello World!到屏幕。这个需求非常简单,任何一个学过一点C语言的人都可以迅速实现:

1 #include <stdio.h>
2 #include <stdlib.h>
3  
4 int main()
5 {
6     printf("Hello World!");
7  
8     return 0;
9 }

  但如果用C++的类来写,就要复杂得多。

01 #include <cstdio>
02 #include <cstdlib>
03  
04 class Output
05 {
06     public:
07         void print(char *str)
08         {
09             printf("%s",str);
10         }
11 };
12  
13 int main()
14 {
15     Output output;
16     output.print("Hello World");
17  
18     return 0;
19 }

  显而易见的是,C++的版本要复杂得多,那么,我们为什么要用C++?C++的优势何在?我们继续改动我们的程序。接下来,假设客户又增加了需 求,希望能输出多个字符串。于是,我们可以建立多个Output类型的变量,以适应需求变动。而C语言代码可以通过多个printf函数解决这次需求变 动。

  然后,客户目前的需求又有所改变:客户要求设计一个开关,可以控制是否输出字符串。针对这个需求变动,我们可以写出这样的C++代码:

01 #include <cstdio>
02 #include <cstdlib>
03  
04 class Output
05 {
06 public:
07     void print(char *str)
08     {
09         if(state)
10             printf("%s",str);
11     }
12     void setState(bool enabled)
13     {
14         state=enabled;
15     }
16 private:
17     bool state;
18     //If true, then output is enabled.
19     //Otherwise, output is disabled.
20 };
21  
22 int main()
23 {
24     Output output;
25     output.setState(true);
26     output.print("Hello World");
27  
28     return 0;
29 }

这样,所有的Output就都具有了开关。而C语言代码就需要一个相对规模较大的重构才可以应对这个变动的需求。

  从上面那个例子我们可以看出,同样的功能,无论是C还是C++往往都有能力去实现。不同点在于可维护性。前面的代码不断被修改的直接原因就在于需求变化。需求的不断变化才是问题的关键。 如果代码是一次性的,针对某一特定问题的,不会变化的,那么怎样实现都可以。在这方面很难体现出类的优势。这也是为什么写了这么多年的NOIP的题目,笔 者依旧难以深入理解类。题目是死的,没有需求上的变动。但大型软件不一样,它会随着时间的发展而发展,随着新需求的出现而不断变化。而且越大型的软件遇到 一次需求变动时,需要改动的代码可能就越多。而C++类便是针对这一问题的一种解决方案。有了类的抽象,需求的变动对代码的影响就减小了很多。这样,软件 的维护成本就被大规模地降低了。

  总而言之,C++的类是为了解决软件开发中不断的需求变化而生的。在必要的时候抽象具体的细节,以减小变化对代码造成的影响。这就是类的作用。

后记

  C++总被人认为是最难以精通的语言。它提供了大量特性,类、模板等等。但同时,它也保留了C语言的面向过程。它犹如一把瑞士军刀,提供了大量 的功能,是解决问题的利器。但同时,它也信任程序员能够恰当地选用合适的工具(瑞士军刀提供了很多工具)。根据具体的需求和可能的需求变动谨慎使用它,才 是正确的做法。例如在NOIP这类的程序中就不使用复杂的抽象,因为题目是死的,几乎没有需求变动。速度才是关键。一些功能清晰的小工具也不必使用太过复 杂的抽象,否则就是过度设计了。为不可能的变化而设计,也会增加软件开发的成本。而对于那些在可预见的时间内规模会迅速增长的程序,抽象就十分有必要了。 根据可预见的需求,使用恰当的程序语言表达,才是正确的。

  综上所述,我的思路好像还是不太清晰。[joke:)]

[转贴]关于C++的抽象的一点新认识的更多相关文章

  1. 最近使用Nginx的一点新得

    1.基本的负载配置 Nginx最简单的配置模块如下 upstream name{ server ip:port; server ip:port; } server { listen 80; serve ...

  2. python 中的一点新知识

    逻辑行与物理行 所谓物理行(Physical Line)是你在编写程序时 你所看到 的内容.所谓逻辑行(Logical Line)是 Python 所看到 的单个语句.Python 会假定每一 物理行 ...

  3. 工控PLC中,关于定时器TON,TOF,的一点新认知,或者说醒悟吧!

    PLC  中的定时器,都是放在一个具体PRG任务单元中的,而PRG单元需要放在具体固定的周期循环任务中才能被执行,而这个周期循环任务的循环周期 T: 与定时器的定时时间T0:    T与T0 的数量级 ...

  4. 译|调整JavaScript抽象的迭代方案

    原文作者:Kaloyan Kosev 原文链接:https://css-tricks.com/adapting-javascript-abstractions-time/ 翻译译者:小溪里 校对:华翔 ...

  5. 调整JavaScript抽象的迭代方案

    原文链接:Adapting JavaScript Abstractions Over Time 译者:小溪里 校对者:郭华翔.苗冬青 即使还没有读过我的文章<在处理网络数据的 JavaScrip ...

  6. C++默认构造函数的一点说明

    大多数C++书籍都说在我们没有自己定义构造函数的时候,编译器会自动生成默认构造函数.其实这句话我一直也是 深信不疑.但是最近看了一些资料让我有了一点新的认识. 其实我觉得大多数C++书籍之所以这样描述 ...

  7. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

  8. Java-马士兵设计模式学习笔记-工厂模式-抽象工厂模式

    一.概述 1.抽象工厂:当情况是需要产生一系列产品,若需更换产品,则要求一系列产品一起换,且要控制一系列产品的产生过程,此时可考虑抽象工厂模式.例:小明装修屋子,把电视.冰箱都替换掉,他这次需要把电视 ...

  9. .NET项目开发—浅谈面向接口编程、可测试性、单元测试、迭代重构(项目小结)

    阅读目录: 1.开篇介绍 2.迭代测试.重构(强制性面向接口编程,要求代码具有可测试性) 2.1.面向接口编程的两个设计误区 2.1.1.接口的依赖倒置 2.1.2.接口对实体的抽象 2.2.迭代单元 ...

随机推荐

  1. Windows Thrift安装及HelloWorld

    Thrift是一个facebook开源的高效RPC框架,其主要特点是跨语言及二进制高效传输(除了二进制,也支持json等常用序列化机制),官网地址:http://thrift.apache.org 跨 ...

  2. case when then 与 count联合使用

    我们都知道SQL中适用case when then来转化数据库中的信息 比如  select (case sex when 0 then '男' else '女' end) AS sex  from ...

  3. Activiti工作流引擎使用

    http://www.kafeitu.me/activiti/2012/03/22/workflow-activiti-action.html 1.简单介工作流引擎与Activiti 对于工作流引擎的 ...

  4. DotNet Core 之旅(一)

    1.下载安装 DotNetCore.1.0.0-SDK.Preview2-x64.exe 下载链接:https://www.microsoft.com/net/download ps:如果有vs201 ...

  5. C10K问题2

    http://blog.csdn.net/zhoudaxia/article/details/12920993 是时候让 Web 服务器同时处理一万客户端了,你不觉得吗?毕竟,现在的 Web 是一个大 ...

  6. windows访问linux共享

    1. 安装samba yum install  samba 2. 配置samba配置文件,添加共享文件夹 vim   /etc/samba/smb.conf 3. 关闭selinux vi  /etc ...

  7. 常用JS正则表达式收集

    1.去掉字符串前后空格,不会修改原有字符串,返回新串.str.replace(/(^\s*)|(\s*$)/g,'');

  8. Constants in C++

    The first motivation for const seems to have been to eliminate the use of preprocessor #define for v ...

  9. 专题二、ArrayList序列化技术细节详解

    一.绪论 所谓的JAVA序列化与反序列化,序列化就是将JAVA 对象以一种的形式保持,比如存放到硬盘,或是用于传输.反序列化是序列化的一个逆过程. JAVA规定被序列化的对象必须实现java.io.S ...

  10. javascript 返回顶部

    <style> #linGoTopBtn {    POSITION: fixed; TEXT-ALIGN: center; LINE-HEIGHT: 30px; WIDTH: 30px; ...