C++批判的批判

来源:互联网 发布:gjb 军用软件版本说明 编辑:程序博客网 时间:2024/04/28 16:23

1,typedef不必要?

a,typedef提供了一层间接,面向对象语言中,接口掩盖了运行时不同具体类型间的差别,而typedef掩盖了编译时不同类型间的差别,却又不丧失类型安全性
b,一般语言只能返回“值”,而typedef提供了返回“类型”的能力,这是模板元编程不可或缺的机制,除非模板元编程眼下也是不必要的

2,导入

在不同地点分别对#include,private成员放在头文件中,inline函数也放在头文件中进行了批判,实际上原因只有一个:C++不是平台,它没有二进制标准,它编译后成为本地代码,丧失了一切类型信息;只有解决了这个问题,才能解决跟分发重用导入相关的各种问题

3,引用是多余的?会被破坏

a,资源释放问题引用比指针更明确,即提供原始对象一方负责释放资源,而一旦用指针做接口参数,就需要约定谁来释放资源
b,空引用在well-formed的程序中是不存在的,因为产生它的唯一方式是提领空指针,而提领空指针是未定义的行为,程序很快就会出错,而不是像被破坏的指针一样,有些运算出错,有些不出,有时出错,有时不出

C99也加入了对引用的支持

4,直接重复继承

C++缺乏Eiffel拥有的“直接重复继承”机制,但假如有的话,语义是什么呢?没看过Eiffel,不懂

5,多重继承

论述较为精辟,对多重处理的继承是C++的软肋,Java禁止了多重实现继承,但提供的“单实现继承+多接口继承+内部类”却又缺乏灵活性和直观性

6,内部类破坏面向对象?破坏复用性

有失公允,除非面向对象排斥面向接口,复用仅止源代码复用;1,内部类提供更好的封装性;2,内部类经过简单包装后可以以可执行代码的形式提供面向接口的复用,一个例子是“List Collections.unmodifiedList(List)”,可用内部类优雅的实现(不知实际实现如何)

7,virtual/override

C++与C#的做法给了基类作者巨大的责任,而这些本应子类作者承担;包括C++里的虚基类,子类的变化迫使父类作出改动

8,虚拟类型

文中说C++只提供了参数化类,没提供虚拟类型,可从所举的虚拟类型的例子来看,似乎用前文所鄙视的typedef即可完成,不知是否如此.

9,束缚多态

在C++里一般称为模板参数约束,正考虑加入下版标准;但如果只是用在书中所举例子,模板参数约束为实现某个接口,那么用接口做为参数就可以了,为什么还要泛型呢?泛型表达了一种Concept,泛参检查也应该为Concept Check,而不是Type Check

10,访问控制

Eiffel对子类访问权限不加限制只能算是一个特性,未必是优点;基于对复用的两种不同理解和侧重,C++和Eiffel选择了对待子类的两种不同态度;对C++私有继承批评时所举的例子并不恰当,造成问题的根源是强制转型,而不是私有继承

11,展开对象

对“.”和“->”的批评太孤立了,实际上“->”是可重载的操作符,提供了一层间接,利用这层间接可以做很多事情:资源管理,以包容的方式获得继承的便利(自动“拥有”被包容对象的方法)等等;Eiffel提供了“展开对象”,不知具体语义如何

12,直接重复继承

翻到这里才看到了Eiffel中直接重复继承的一种用处:原来是为了在子类中调用父类同名方法;随着Precursor加入语言,这种用法也可以被抛弃了

13,抗变与协变

返回值协变似乎没多大问题,参数抗变似乎也没多大问题,问题在于参数协变;Eiffel提供了Current和like来解决,C++只能期待受束泛型了

14,强制针对接口编程

作者认为父类中的public成员在子类中重定义时改为protected或private会带来协变问题,其实只要重定义函数的语义正确,也没什么;而且这种变化会带来另外一种效果:强制针对接口编程;因为此时你的客户程序员只能通过父类来引用你的子类对象才能访问重定义的成员

15,垃圾收集

还是那些话题,还是那些论调,还是对内存外的资源管理避而不谈;难道不能“析构函数+栈对象+堆对象垃圾收集”?C++只不过缺省缺少“堆对象垃圾收集”,智能指针还能撑一会,Java和Eiffel则缺少“栈对象+析构函数”

16,契约式设计与CORBA IDL

作者认为CORBA IDL不支持契约式设计是一个缺陷,可我从来不敢在我的DCOM,RMI,.Net Remoting组件中使用断言,包括最初的socket server;这可是暴露在网络环境中啊,违反前置条件是要抛异常的啊;WebService稍好一点,明确定义了异常处理,有中间件支持

原创粉丝点击