飞道的博客

为什么使用C++?————深层次讲解

311人阅读  评论(0)


通常语言都是一种工具,无论是编程语言还是其他语言。追根溯源就是解决问题的工具。通常都不是为了特定的工具挑选合适的问题,而是为了选择被该软件兼容的工具。**对待任何编程语言的态度都是合适时,就采用这一种,如果另一种更管用,就选用另一种。**因此如何选择一门编程语言是十分重要的。

1 C++特点

  • 1 抽象
  • 选择性忽略此时可并不重视的因素,隐藏用户无需关心的抽象工作细节。
  • 2 考虑特殊用户群。
  • 执行速度块,可移植性强,与硬件和其他软件系统的借口简单(保留了C的特色)。
  • 3 实用性
    • 灵活性,编写不完整的类(如果类够用的话),一般折中的方案比未来理想的方案好的多(区别于懒惰主义,可以把C++把问题划分成分割良好的模块,使模块间信息得到良好的隐藏)。

2 为什么使用C++?

其实一开始我以为自己使用的就是C++,但是到了后面才发现,自己使用的不过是C,基本上都是面向过程的编程思想。类、继承、多态、STL、泛型编程基本上都没有用到,可谓是打着C++的名号使用C。

C++具有很多优势,第一就是可移植性。

C++可以在任何已存在的环境中运行。大多数环境都是传统环境(程序交给编译器编译,编译器把相应的机器代码放在一个文件,连接程序读取这个文件,把这些机器指令和相关的库中的机器指令结合在一起,放在另一个文件,得到这个文件的命令后,操作系统把文件读入内存,并且跳转到文件的第一条指令)

有的语言要有他们自己的编译环境,比如APL、Lisp、Basic、Smalltalk。有一些语言尤其难以与其环境分离,比如Smalltalk,也很难愤青那里是程序或者是系统环境。Lisp则采用一种S-expression的表识。程序和数据都是内部S-expression的实例,但是当处理不能很好符合S-expression模式的数据时,Lisp就会陷入困境。比如很难针对存储在磁带中的户口普查资料、或者类似与局域网或风洞这样奇怪的I/O设备编写Lisp。

以前C语句是可以移植的,Smalltalk、Lisp、Snobol也是可以移植的,但是这些语言都有垃圾回收机制【系统开销大】和可扩展的数据结构。这就带来了问题,问题是内存不用了,要等垃圾收集机制发现之后才释放,在要求系统的运行速度、编译器和运行时系统复杂度方法付出了代价,而且只释放内存。但是使用C++可以使用构造函数和析构函数控制对缓存区的分配和释放。(缓冲区必须要在文件关闭前释放)

如果一个机器支持C,那么支持C++就会有很大的困难。也就是C++几乎可以在任何地方运行,没有对复杂环境的依赖性,譬如不需要对收集机制或者交互执行等功能的支持。

这就是为什么可以在照相机这样的电子设备中运行c++程序;为了粒子物理学家可以在他们的桌面工作站调试算法,在把相同的程序放到具有可以充分发挥并行优势的数据库的超级计算机上运行;为什么最简单环境也可以编译下载和编译C++;许多用C写的大型项目转使用C++,而无需重写所有的代码。

第二就是字符串的使用。
C++的字符串可以动态增加大小(成员函数),自动释放内存(析构函数),而C语言使用字符数组时,大小是静态的(不好决定),必须手动释放内存(释放的时机不好确定)。总结起来就是字符串已经帮我们自动管理了内存(类似于句柄类【代理类】),不用我们记住一些隐匿的规定(如要知道分配内存的大小;不使用超过分配内存外的内存;不再需要时释放内存呢;只有不再需要时,才释放内存;只释放分配的内存;切记检查每个分配请求,以确保成功)

第三类的使用。
使用C++编程时,只要用类来抓住问题的本质,然后使这个类能独立工作,一般编译一次就能解决问题。

许多最成功、最有名的软件最初都是由极少数人开发的。许多真正的赢家都是从小系统做起,比如UNIX操作系统、C语言、FORTRAN、MS-DOS、VM730(完全在IBM正规生产线外发展起来)。

为什么大项目不容易成功,因为软件制造的规模化和经济效益不成正比,绝大数称职的程序员能在一两个小时内写完一个100行的程序,而大项目的通常每个程序员每天都平均只写10行代码。

当一个项目成员多到不能同时坐在一张餐桌时,交流上的开销就会相当严重,项目成员会把事件用于处理除编程外的任何事情上,比如阅读、编写、回顾需求报告;管理错误报告数据库;参加会议、处理规范。

软件和工厂的流水线生产不一样,工厂是制造大量相同的产品,生产过程中充分利用了分工的优势,而软件开发是生产数量先对较少、彼此完全不同的人造产品。软件开发应该想机械修理厂,熟练的技工可以利用手边所有可用的精密工具来提高工作效率。

实际上,只要在可控的范围内,称职的程序员总是争取让机器代替自己做他们所能完成的机械工作。(毕竟机器擅长干这样的活)
随着项目规模剧增,把程序员看作手工艺人的观点变得难以支持,因为为了描述一个庞大的编程问题,需要把大系统中各小项目之间的关系理顺,也就是需要项目间的接口(子程序和数据结构的抽象),每个项目成员几乎不需要关心接口以外的东西。

而C++提供了这样的抽象,就是类,使用构造和析构函数表示数据结构的初始化和终止,同时使用其他成员函数,是想对内存的动态管理。

有些抽象不是语言的一部分,比如文件,文件是数据结构和程序的集合,长期存储数据的一种方式,为了防止无意间修改数据,因此一般都在文件间构筑“防火墙”。

第四:状态信息。
C语言没有合适的地方来存储辅助的状态信息,可能原本不需要状态信息,到后来才知道需要。解决的办法就是找的地方把它隐藏,如下面的例子,但是如果要输出多个文件来搅局,就很难控制了;C++可以采用类表示类似输出流的事务,这里可以提供一个理想的位置来放置状态信息。
C倾向于不存储状态信息,除非事先已经规划妥当。C程序员趋向于假设这样一个环境,存在一个位置集合,他们可以在其中找到系统当前的状态。但系统在不断增加的过程中,往往会引入某些独一无二的东西,并创造更多这类的东西。

3 简单的例子说服他人使用C++?

实现功能打印信息,在有必要时关闭跟踪输出。

#include <cstdio>

class Trace{
public:
    Trace():noisy(0),f(stdout){}
    Trace(FILE* ff){noisy = 0; f = ff;}
    void print(char* s){
        if(noisy) fprintf(f, "%s", s);}
    void on(){noisy = 1;}
    void off(){noisy = 0;}
private:
    int noisy;
    FILE* f;
};

int main(){
    Trace t(stdout);
    t.on();
    t.print("begin main()\n");
    t.print("end main()\n");
    return 0;
}

C语言

#include <cstdio>
static  int noisy = 1;
void trace(char* s){
    if(noisy) printf("%s\n",s);
}
void trace_on(){
    noisy = 1;
}
void trace_off(){
    noisy = 0;
}


int main(){
    trace("begin main()\n");
    trace("end main()\n");
    return 0;
}

缺点:

  • 1 函数trace不是内联的。因此在跟踪关闭时,他还保持着函数调用的开销;
  • 2 引入三个局部名称trace、trace_on、trace_off,而C++只因入一个;
  • 3 很难将这例子一般化,使之输出到一个以上的文件。因为C语言的方法就是对trace增加参数,需要找到所有对trace调用,并插入这个新增的参数。另一个办法就是引入trace_out的第四个函数,将跟踪输出转向到其他文件。

转载:https://blog.csdn.net/qq_33375598/article/details/105589448
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场