1、代码膨胀
C++分别编译过程中以及模板重复实例化引起的代码膨胀有时可能非常惊人。一方面消耗大量的编译时间,另一方面执行时代码过大引起多次的磁盘操作,影响执行速度。
2、异常完全和出错信息问题
STL 不象Java 定义了完整的异常。实际上STL 只有为数不多的几种异常类型。许多时候导致程序员调试工作大大增加。模板机制套用宏机制,因此只有在真正编译链接时才能看到模板引起的错误消息,这些消息数目巨大,而且表现为编译错误和链接错误,程序员无法找到错误的真正所在。
因此设计更加强大的编译器,使得模板称为语言内部机制,而不是象宏机制一样的预处理机制,从长远看这是很有必要的,另一方面丰富语言调试机制,使得STL 可以定制错误消息,或者专门设计STL 相关的出错信息。
3、模块机制
C++在许多特性方面毫无必要的与C 兼容,象模块机制,C++也简单采用C 的头文件机制,头文件机制已经很不适应现代程序设计的需要,C++应该提供一套更加完善的模块机制。
编译模式过于复杂,尤其是针对模板的分离编译模式,概念不够统一清晰,仍然保留C的分别编译模式和头文件包含,很容易产生名字冲突,尤其时头文件的重复包含及其繁琐,应该由编译器自动解决。
4、符号重载与代数性质不全等的问题
如全序,代数意义与运算符重载下的意义不完全一致,可能潜藏问题。另外C++并没有方便形式化方法的机制,因此无法验证类型是否符合其声称的代数性质。实际上在C++中根本不适合采用形式化方法来检验程序。
5、函数对象与函数式语言中的函数的差别
C++非常关注效率,因此尽管有许多呼声要求在C++中增加一些函数式程序设计语言的成分,Stroutrup 还是放弃了这些高阶语言成分。作为C++语言的核心可以控制高阶成分的引入,但是没有理由禁止在库级别引入高阶成分。虽然函数对象开始进入STL 中,但是距离真正的高阶函数还是有不少距离。函数对象只是重载括号运算符,不能像函数式语言那样将函数作为操作对象,不能实现函数式语言的程序设计方法。因此在STL 中引入高阶成分的途径之一是在库级别引入一些特性,使得可以采用函数式语言程序设计风格来设计程序。
6、C++对泛型编程的支持不够
只有早期绑定,没有后期绑定,实际上C++没有给程序员选择;不能很好的支持concept,即无法形式化的支持接口,没有指向concpet 的指针,无法检查concept;因为模板实现采用预处理方式,因此C++对模板采用延迟实例化方式,只有使用时才实例化模板,同时对模板进行静态检查,如果模板没有被实例化,其中语法错误可能隐藏很久。
7、STL 实现中的大量冗余拷贝
STL 在实现时参数传递等许多地方出现冗余拷贝。整个STL 还需仔细设计,尤其是STL的内存管理部分,设计好的话可以在一定程度上采用引用语义。如果只采用采用值语义,实际编程中会产生大量的中间复制操作。
8、宏机制和内联函数
C++并不能保证内联函数一定展开,许多时候,尤其是编写系统软件,需要强制某个函数展开。其次宏机制效率高,而C++的虚函数因为需要查找虚表,效率上有损失,MFC 的消息映射就采用宏机制而避免采用虚函数。实际上用宏机制也有许多好的程序设计方法,仅用内联函数是无法代替宏机制的,有没有一种机制能吸收两者的优点,同时摒弃其缺点呢?
参考:
1、C++ STL 体系结构、编程方法及存在的问题,李健