我仍然觉得C++提供了一些无法打败的东西.我不打算在这里开始一场火焰战,如果你对不喜欢C++有强烈的意见,请不要在这里发泄它们.我很想听听C++大师们为什么坚持下去.
我对C++的方面特别感兴趣,这些方面鲜为人知或未充分利用.
编辑:人们,请至少粗略阅读其他回复,以确保你没有复制已经说过的内容,如果你同意别人所说的话,那就投票吧!
RAII /确定性最终确定.不,当您处理稀缺的共享资源时,垃圾收集不是那么好.
对OS API的不受限制的访问.
我一直坚持使用C++,因为它仍然是性能最高的通用语言,适用于需要结合效率和复杂性的应用程序.作为一个例子,我为测量行业编写了用于手持设备的实时表面建模软件.鉴于资源有限,Java,C#等......只是没有提供必要的性能特征,而像C这样的低级语言在较弱的抽象特性下开发要慢得多.C++开发人员可用的抽象级别范围很大,在一个极端我可以重载算术运算符,这样我可以说像MaterialVolume = DesignSurface - GroundSurface同时运行多个不同的堆来为我的应用在特定设备上最有效地管理内存.将它与丰富的免费资源相结合,可以解决几乎任何常见问题,而且你有一种强大的开发语言.
C++仍然是大多数域中大多数问题的最佳开发解决方案吗?可能不是,虽然在紧要关头它仍然可以用于大多数.它仍然是高效开发高性能应用程序的最佳解决方案吗?恕我直言,毫无疑问.
在脚下射击自己.
没有其他语言能提供如此创造性的工具.指针,多重继承,模板,运算符重载和预处理器.
一种非常强大的语言,也提供了足够的射门机会.
编辑:如果我对幽默的蹩脚尝试冒犯了一些,我道歉.我认为C++是我曾经使用过的最强大的语言 - 能够在需要时在汇编语言级别进行编码,并在需要时进行高级抽象.自90年代初以来,C++一直是我的主要语言.
我的回答是基于多年拍摄自己的经验.至少C++允许我优雅地这样做.
确定性的物体破坏导致一些宏伟的设计模式.例如,虽然RAII不像垃圾收集那样通用,但它会带来一些令人印象深刻的功能,而这些功能是GC无法实现的.
C++也是独一无二的,因为它有一个图灵完备的预处理器.这允许您更喜欢(与推迟相反)许多代码任务来编译时间而不是运行时间.例如,在实际代码中,您可能有一个assert()语句来测试永远不会发生的事情.现实是它迟早会发生......并且在你休假时凌晨3点发生.C++预处理器断言在编译时执行相同的测试.编译时断言在上午8:00到下午5:00之间失败,而您坐在电脑前观看代码构建; 当你在夏威夷睡着时,运行时断言在凌晨3点失败.在那里看到胜利很容易.
在大多数语言中,策略模式在运行时完成,并在类型不匹配时抛出异常.在C++中,策略可以在编译时通过预处理器工具完成,并且可以保证类型安全.
编写内联汇编(MMX,SSE等).
确定性对象破坏.即真正的析构函数.使管理稀缺资源变得更容易.允许RAII.
更容易访问结构化二进制数据.将内存区域作为结构转换比解析它并将每个值复制到结构中更容易.
多重继承.并非一切都可以通过接口完成.有时您也想继承实际功能.
我想我只是赞扬C++能够使用模板捕获表达式并在需要时懒惰地执行它.对于那些不知道这是什么的人,这里有一个例子.
模板mixins提供了我在其他地方没见过的重用.有了他们,仿佛你已经手写了整个事情,你可以建立一个有很多行为的一个较大的对象.但它的功能这些小的方面可以重复使用,这是实现接口(或整个事情),你在哪里实现多个接口部分特别大.生成的对象是闪电般快速的,因为它全部内联.
速度可能并不重要在许多情况下,但是当你编写组件软件,而用户可能会将在组件未想到的,复杂的方式来做事,内联的速度和C++似乎允许创建更加复杂的结构.
在需要时绝对控制内存布局,对齐和访问.如果你足够小心,你可以编写一些非常缓存的程序.对于多处理器程序,您还可以消除缓存一致性机制中的大量减速.
(好的,你可以用C语言,汇编语言,也可能用Fortran语言.但C++允许你在更高级别编写你的程序的其余部分.)
这可能不是一个流行的答案,但我认为C++与众不同的是它的编译时功能,例如模板和#define.您可以使用这些功能对程序执行各种文本操作,其中大部分功能已在后面的语言中以简单的名义放弃.对我而言,这比在C++中更容易或更快的任何低级别的比特更重要.
例如,C#没有真正的宏设施.您不能将另一个文件直接#include到源中,或使用#define将该程序作为文本进行操作.想想任何时候你必须机械地键入重复代码,你知道有更好的方法.您甚至可能已经编写了一个程序来为您生成代码.好吧,C++预处理器可以自动完成所有这些事情.
与C++模板相比,C#中的"泛型"工具同样受限制.C++允许您盲目地将点运算符应用于模板类型T,调用(例如)可能不存在的方法,并且只有在模板实际应用于特定类时才应用检查正确性.当发生这种情况时,如果您对T做出的所有假设实际成立,那么您的代码将会编译.C#不允许这样......类型"T"基本上必须作为一个对象来处理,即只使用可用于所有事物的最低公共分母(赋值,GetHashCode(),Equals()).
C#以简单的名义废除了预处理器和真正的泛型.不幸的是,当我使用C#时,我发现自己正在寻找这些C++结构的替代品,这些结构不可避免地比C++方法更加臃肿和分层.例如,我见过程序员以几种臃肿的方式解决缺少#include的问题:动态链接到外部程序集,在几个位置重新定义常量(每个项目一个文件)或从数据库中选择常量等.
正如辛普森的Crabapple女士曾经说过的那样,这是"相当蹩脚的,米尔豪斯."
在计算机科学方面,C++的这些编译时功能支持诸如逐个名称参数传递之类的东西,已知它比按值调用和按引用调用更强大.
同样,这可能不是流行的答案 - 例如,任何介绍性的C++文本都会警告你#define.但是多年来我一直在使用各种各样的语言,并且考虑到所有这些背后的理论,我认为很多人都给出了不好的建议.在称为"IT"的稀释子领域中尤其如此.
C#和Java强迫你将'main()'函数放在一个类中.我发现这很奇怪,因为它淡化了一个阶级的意义.
对我来说,类是问题域中的一类对象.程序不是这样的对象.所以在你的程序中永远不应该有一个名为"Program"的类.这相当于使用符号来表示自身的数学证明 - 证明 - 以及表示数学对象的符号.这将是奇怪和不一致.
幸运的是,与C#和Java不同,C++允许全局函数.这让你的main()函数存在于外部.因此,C++提供了一种更简单,更一致,也许更真实的面向对象习惯用法.因此,这是C++可以做的一件事,但C#和Java不能.
以最小的开销在进程间传递POD结构.换句话说,它允许我们轻松处理二进制数据的blob.