C++语言积累了庞大的代码基,这个代码基不是一朝一夕能够推翻的。D从语言角度来说的确优于C++语言,但最关键的就是还没有深入工业界,希望本文能教会你更多东西。
对于编写的函数,除了明确的指定契约外,在函数开始处应该对传入的参数进行检查,确保非法参数传入时立即报告错误信息。例如:
- BOOL GetPathItem ( int i , LPTSTR szItem , int iLen )
- {
- ASSERT ( i > 0 ) ;
- ASSERT ( NULL != szItem ) ;
- ASSERT ( ( iLen > 0 ) && ( iLen < MAX_PATH ) ) ;
- ASSERT ( FALSE == IsBadWriteStringPtr ( szItem , iLen ) ) ;
- }
- 对指针的检查尤其要注意,通常程序员会这样进行检查:
- // An example of checking only a part of the error condition
- BOOL EnumerateListItems ( PFNELCALLBACK pfnCallback )
- {
- ASSERT ( NULL != pfnCallback ) ;
- }
在上面的例子中,switch语句仅仅处理了GK_ENTITY_POINT和GK_ENTITY_PLINE两种情况,应该是系统中当时只需要处理这两种情况,但是如果后期系统需要处理更多的情况,而此时上面这部分代码又没有及时更新,或者是因为开发人员一时疏忽遗漏了。一个可能导致系统错误或者崩溃的bug就出现了,而使用ASSERT可以及时地提醒开发人员他的疏忽,尽可能快的消灭这个bug。
还有一些情况,在开发人员编写代码时,如果能够确信在某一点出现情况A就是错误的,那么就可以在该处加上ASSERT,排除情况A。综上所述,恰当、灵活的使用ASSERT进行主动调试,能够极大提高程序的稳定性和安全性,减少调试时间,提高工作效率。
一些好的代码风格也能够帮助你避免一些幼稚的、低级的错误,而这种错误又是很难检测到的。由于C++语言简洁灵活的特性,有时候敲错一个字符。或者漏敲一个字符,都有可能造成极大的灾难,而这种错误并不是随着你的编程水平和经验的提高就能逐步避免的,谁都会敲错字符,对吧。
比如程序员经常将等于逻辑判断符==误敲成赋值运算符=,对于我来说就不太可能程序运行出错后才发现,因为我的习惯是,对于逻辑判断,将常量置于==的左边,如果我误输入了=,那么编译的时候编译器就会报错。
法),无异于因噎废食。”在所有可用C和C++的领域,C++都是比C更好的语言。当我说“更好的”时候,我说的是C++拥有比C更安全的类型检查、更好的抽象机制、更优秀的库。当然,凡事都有例外,如果你做的项目1)不大。
编码中用不到什么抽象机制,甚至ADT(抽象数据类型,例如std::complex这种不含多态和继承的)也用不到,RAII也用不到,异常也用不到。你连基础库(如,简化资源管理的智能指针、智能容器)都用不着。那么也许你用C的确没问题;所以如果你的情况如此,不用和我争论,因为我无法反驳你。我们这里说的领域大致是Bjarne在“C++应用列表”里面列出来的那些地方。 #t#
底线是:如果把C++中的诸多不必要的复杂性去掉,留下那些本质的,重要的语言特性,简化语言模型,消除历史包袱。即便是C++的反对者也许也很难找到理由说“我还是不用C++”。在我看来,一个真正从实践意义上理性反对使用C++语言的人只有一个理由:C++的复杂性带来的混乱抵消乃至超过了C++的抽象机制和库(在他的特定项目中)带来的好处。
值得注意的是,这里需要避免一个陷阱,就是一旦人们认定了“C++语言不好”,那么这个理由就会“长出自己的脚来”,即,就算我们拿掉C++的复杂性,他们可能也会坚持还是不用C++,并为之找一堆理由。我假定你不是这样的人。
不过,也许最可能的是他会说:“问题是我们今天用的C++并非如此(简洁),你的假设不成立。”是的,我的假设不成立。但虽然我们无法消除复杂性,我们实际上是可以容易地避开复杂性,避短扬长的。这也是本文的要点,容我后面再详述。
当然,到现在你可能还是会说。我还是不用C++语言,因为我可以用D;或者如果你本来做的项目就不需要C++,你则可能会说,我用Python。首先,如果你的项目能用Java/Python乃至Ruby做,那么用C++是自讨苦吃。
因为能用那些语言代表你的项目在效率上本身要求就不高,那么用一门效率上讨不到太大好处,复杂性上却绰绰有余的语言,有什么价值呢?其次,如果你的项目效率是很重要的,你可能会说可以用D。