C++中的不良设计

来源:互联网 发布:淘宝网宁夏枸杞 编辑:程序博客网 时间:2024/04/29 14:06

 

  首先声明,起这么一个标题,目的是为了“耸人听闻”,吸引读者。:) 文中的两个函数的缺陷,不是我所发现,只是我认为很有意义,与大家共享。而且,可以了解一个成熟系统的“缺陷”,不是非常让人愉快和兴奋吗?

  本文的部分内容引用了林锐的《高质量C++/C编程指南》一书。(建议大家都去读读,尤其我找工作的时候,不少小公司直接使用了书中的C++试题作为笔试题目 :) )

1: printf()

相信大家都使用过,MFC 中的TRACE有同样的问题。printf()的缺陷是不安全性和不可扩展性。

1)关于不安全性,《高质量C++/C编程指南》一书有明确的解释:

【建议6-1-2】尽量不要使用类型和数目不确定的参数。

C标准库函数printf是采用不确定参数的典型代表,其原型为:

int printf(const chat *format[, argument]…);

这种风格的函数在编译时丧失了严格的类型安全检查。

int i;

printf("%s",i);  // 编译时无法使用严格的类型安全检查。

 

2)关于不可扩展性,是指它不可以和自定义的类型配合使用。请看以下代码:

int i;

float f;

CStudent student; // 自定义的类型,其中重载了 << 操作符

cout << i << f << student;

printf("%d %f",i,f); // 不能和student配合使用

 

2. getchar()函数,《高质量C++/C编程指南》一书有明确的解释

       1)  【规则6-2-2】函数名字与返回值类型在语义上不可冲突。

违反这条规则的典型代表是C标准库函数getchar。

例如:

char c;

c = getchar();

if (c == EOF)

按照getchar名字的意思,将变量c声明为char类型是很自然的事情。但不幸的是getchar的确不是char类型,而是int类型,其原型如下:

        int getchar(void);

由于c是char类型,取值范围是[-128,127],如果宏EOF的值在char的取值范围之外,那么if语句将总是失败,这种“危险”人们一般哪里料得到!导致本例错误的责任并不在用户,是函数getchar误导了使用者。

 

  2) 【规则6-2-3】不要将正常值和错误标志混在一起返回。正常值用输出参数获得,而错误标志用return语句返回。

回顾上例,C标准库函数的设计者为什么要将getchar声明为令人迷糊的int类型呢?他会那么傻吗?

在正常情况下,getchar的确返回单个字符。但如果getchar碰到文件结束标志或发生读错误,它必须返回一个标志EOF。为了区别于正常的字符,只好将EOF定义为负数(通常为负1)。因此函数getchar就成了int类型。

我们在实际工作中,经常会碰到上述令人为难的问题。为了避免出现误解,我们应该将正常值和错误标志分开。即:正常值用输出参数获得,而错误标志用return语句返回。

函数getchar可以改写成 BOOL GetChar(char *c);

虽然gechar比GetChar灵活,例如 putchar(getchar()); 但是如果getchar用错了,它的灵活性又有什么用呢?