c和c++的区别的一些个人见解

前言

为了能够更加方便的使用到标准的高级数据结构,同时提高代码的扩展性,最近我将之前用C写的一个模块代码改写成C++ 的版本。尽管一直以来C++ 都被认为是C的一个超集,但是通常两者的编程思路是很不相同的,为尽量符合C++ 的编程思想,我却花费不少时间来做修改(或者说是重构)。

很自然的,我随手就搜了一下C和C++ 的区别与联系,于是就发现在知乎上有关于“C 与 C++ 的真正区别在哪里”的讨论,在学习了一众大佬们的讲解后,就发现有大佬谈起了面试中被问到这种问题的情况,他表示与其问这种大而广的玄学问题,还不如问一些实际项目中对于C和C++ 的使用上的心得体会,因为他觉得:我见过很多十几年以上经验的C/C++ 工程师,经历过很多大项目,他们很少提及诸如“C 和 C++ 的真正区别” 这种话题,他们通常关心 “是否稳定,是否可维护,是否扩展性好” 这种问题”,他推测会这样提问的面试官一般很可能是以下这三种情况:1. 已经早已从技术岗位走向管理岗位了 2. 面试官偏向学术 3. 所在团队比较虚、不务实。

对此我深表赞同,面对“C与C++ 的区别在哪里”这样的问题,仅仅从语法角度深入分析都可以写一本数了,更何况还可以从各种各样不同的角度来说明,面试者很难把握面试官到底想了解那一方面。不过我觉得问题既然提出来了,还是可以思考怎样说明会是一个比较好的回答。

C和C++的差异

在回答这个问题的时候,我觉得不应该直接从语法的差异来讲,因为语法的细节太多,如果没有一个主题来统一它的话,那就只能是泛泛而谈。所以我建议从设计角度,从C++ 设计程序相对C的最大特点入手,然后再衍伸出为了达到对这些设计思想良好的支持,C++ 在语法上的所添加的哪些特性。

最近在看《Effective C++ 》一书时,就看到作者对当前C++ 编程范式的说明,他提到“今天的C++ 语言已经是一个多重范式型的编程语言,一个同时支持面向过程,面向对象、函数式编程、泛型编程、元编程”,在这其中“函数式编程”和“元编程”我个人不是很清楚,但是面向对象和泛型编程是深有体会。C++语言对面向对象和泛型编程是提供语法级的支持,使得程序员可以使用很简单的代码达到目的。反观C语言,一般的C编程基本上都是面向过程的,这并不是说C就没法支持面向对象或者是泛型,而是说C没法通过它自身基本的语法特性来实现,即使能够通过复杂而繁琐的代码间接的构建了,也需要面临各种各样的难题需要处理(如性能问题、安全问题)。

首先谈一下面向对象,我们都知道面向对象有三个基本特点:封装、继承、多态。为了达到良好封装的效果,C++ 在C的struct的基础上定义了class。在用法上C的struct通常只是用来打包一群有关联的数据,而C++ 的class除了可以包含数据外,还可以拥有操作这些数据的函数,另外还有一个非常重要的特点就是:class中任何成员都能定义自己的安全属性(包括public、protect、private),这就让一个class既能有对外完全不可见得部分,也有专门用来与外界交互的部分;最后class创建和删除由它自身专门的构造函数和析构函数来控制,这使得一个class就有了自治特性。从上面的分析可以看出C++的class比起C的struct在封装特性上的支持是完全不在同一层次上的。

在说明封装的特性时,如果说C语言能看到一点影子的话,那么继承在C中是完全没有这样的概念的。继承在C++ 中的支持也是基于class的,在C++ 中允许一个class继承与另一个class,从而在不用写重复代码的情况下,从另一个class中获取到它其中的所有的成员(包括成员变量和成员函数)。

也许使用C语言的函数指针也可以牵强的看做是多态的一种体现,但是在C++ 中这种程度的多态支持就显得太弱了。首先虚函数在C++ 的引入是对多态特性强力的支持。在class继承时,C++ 可以将基类中的成员函数定义为虚函数,这样在派生类中就就可以完全重写父类中的虚函数,在调用这个函数时,C++ 会在运行时根据不同调用对象来选择具体调用哪个版本的函数,即派生类的对象调用它自己重写函数,基类对象调用基类中的函数。

以上就是C++ 对面向对象编程支持所拥有的一些主要的语法特性。再来说泛型,C++ 对于泛型的支持相对就单一些,主要就是模板了,但是模板所的作用确是巨大的,它能够让我们定义函数和类时,不用指定特定的参数类型,而将注意力关注到通用的逻辑实现上来,这使得代码的通用性大大增加。而泛型编程最著名莫过于C++ 的标准模板库STL了。

Compartir