前辈论C++缺点

来源:互联网 发布:淘宝店铺金牌卖家 退货 编辑:程序博客网 时间:2024/05/16 15:26
从下一代标准讨论的新内容可以看出需要改进的地方。 

先说异常,异常会损失一定的效率。过去的时候你不用异常也会损失一定效率,不过得益于编译器的进步,现在g++生成的代码如果不使用异常不会有额外的效率损失。 

然后便是:C++不是全异常的,对于已有代码,引入异常不合适。对于新代码来说好一些,但并非所有人都愿意用。有人更习惯通过返回值来进行错误处理。(不过在C++中有时必须使用异常,比如构造) 

粘贴google code style中关于异常的部分: 
----------------------------------- 
优点: 
异常允许上层应用决定如何处理在底层嵌套函数中 “不可能出现的” 失败, 不像错误码记录那么含糊又易出错; 
很多现代语言都使用异常. 引入异常使得 C++ 与 Python, Java 以及其它 C++ 相近的语言更加兼容. 
许多第三方 C++ 库使用异常, 禁用异常将导致很难集成这些库. 
异常是处理构造函数失败的唯一方法. 虽然可以通过工厂函数或 Init() 方法替代异常, 但他们分别需要堆分配或新的 “无效” 状态; 
在测试框架中使用异常确实很方便. 
缺点: 
在现有函数中添加 throw 语句时, 你必须检查所有调用点. 所有调用点得至少有基本的异常安全保护, 否则永远捕获不到异常, 只好 “开心的” 接受程序终止的结果. 例如, 如果 f() 调用了 g(), g() 又调用了 h(), h 抛出的异常被 f 捕获, g 要当心了, 很可能会因疏忽而未被妥善清理. 
更普遍的情况是, 如果使用异常, 光凭查看代码是很难评估程序的控制流: 函数返回点可能在你意料之外. 这回导致代码管理和调试困难. 你可以通过规定何时何地如何使用异常来降低开销, 但是让开发人员必须掌握并理解这些规定带来的代价更大. 
异常安全要求同时采用 RAII 和不同编程实践. 要想轻松编写正确的异常安全代码, 需要大量的支撑机制配合. 另外, 要避免代码读者去理解整个调用结构图, 异常安全代码必须把写持久化状态的逻辑部分隔离到 “提交” 阶段. 它在带来好处的同时, 还有成本 (也许你不得不为了隔离 “提交” 而整出令人费解的代码). 允许使用异常会驱使我们不断为此付出代价, 即使我们觉得这很不划算. 
启用异常使生成的二进制文件体积变大, 延长了编译时间 (或许影响不大), 还可能增加地址空间压力; 
异常的实用性可能会怂恿开发人员在不恰当的时候抛出异常, 或者在不安全的地方从异常中恢复. 例如, 处理非法用户输入时就不应该抛出异常. 如果我们要完全列出这些约束, 这份风格指南会长出很多! 
结论:我们不使用C++异常。 
----------------------------------------- 

然后是模板,模板问题很多。 
首先,使用的模板的代码不支持分离式编译,结果便是一坨代码挤在一个头文件里。 
然后就是编译错误,使用了模板的代码如果编译出错,那么产生的出错信息必然像天书一样,STL是个典型的例子。 
然后就是由模板开始,C++被发掘出了一大堆技巧,而STL和Boost大量使用了这些技巧,这些技巧是十分难懂的。 

上面说了模板不支持分离式编译,于是实现和定义挤在一个头文件中。在C中如果我们这么做,无语会在链接是出现定义冲突的情况。不过还好,C++编译器会搞定这个,代价就是 编译太慢。 

C++的编译速度实在是太慢了,可不要小看这个问题,代码多了这就是个噩梦。 

另外值得一提的是,为了解决分离式编译的问题,C++引入了export关键字,不过这个关键字几乎没有被编译器支持过(export本身也有问题)。 

哪些十分诡异的库是什么库?编写操作系统会用到哪些库么? 
------------------------------------------------- 
十分诡异的库,首推Boost,STL的算法很好,但实现也有点蛋疼。写操作系统通常从头做起,不会使用任何的库。(库的很多功能依赖系统,比如C的malloc,printf,没系统没法用)。 

C++支持函数重载,代价就是引入了函数签名。函数会根据参数的类型生成不同的签名。平时这不会有什么问题,不过如果要和汇编代码链接到一起就麻烦了,在dll中提供对外接口也是问题。所以,虽然Win是用C++和C写成的,API确是C风格的(还有一些原因导致这一点)。 

struct对程序员几乎是完全透明的,通常编译器不会调整struct中程序在内存中布局的顺序(有个特例,gcc有个参数可以允许编译器进行这种调整)。但是C++编译器可能进行这种调整,于是不同的编译器生成的代码在二进制兼容方面就有问题了,这也是Win的API是C风格的一个原因。 

还有就是有关面向对象的部分,和Java/C#比有很大不同,各有优缺点,不过有一点是肯定的,就是:C++复杂的多。
原创粉丝点击