woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

关于更好的编程风格的建议

在这篇文章里我将谈谈各种层次的C++程序员经常问及的四个问题。例如我很惊讶地发现还有很多程序员没有意识到标准头文件扩展名.h的争议,命名空间的恰当用法以及引用临时对象的规则。这些问题及其它将在这里进行讨论。

首先我们从解释受非议的“XXX.h”头文件名与现代、符合标准的“<XXX>”头文件名记号之间的区别开始。接下来我们探索C++不为人知的角落,由于编译器的局限性和关联语言规则某些隐蔽的自然特性迷惑了许多程序员,比如逗号分隔表达式的意义与引用型变量的规则。最后我们将学习如何在程序启动前启动一个函数。

 

话题1“iostream.h” or “iostream”?

C++程序员还在使用“iostream.h”代替新的符合标准的“iostream”库。两者有什么区别呢?首先,标准头文件“.h”扩展名在五年前就倍受争议。在新代码中使用有争议的(过时的)特性永远都不是一个好主意。从本质上看,“iostream”包括一系列支持窄字符与宽字符的模板化(templatized I/O输入输出类,而相反地,“iostream.h”只支持字符流。第三,iostream接口的标准C++规范在许多细节方面进行了变动。因此,“iostream”的接口与实现同那些“iostream.h”是有区别的。最后,“iostream”是在std命名空间中定义的而“iostream.h”则是全局的。

由于这些本质方面的不同,不能在同一程序中混合使用这两种库。作为一个规则,应尽量使用“iostream”,除非你要处理的是只能与“iostream.h”兼容的遗留代码。

 

话题2:将引用与右值绑定

右值和左值是C++编程的一个基本概念。本质上来讲右值是一个不可能出现在等号左边的表达式。相反,左值引用一个对象(广义范围上的),或者一块可读写的内存。引用既可以指向右值也可以指向左值。然而,由于语言在处理右值上的限制,你也得在将引用指向右值是慎重考虑。

将引用与右值绑定像引用常量一样也是被允许的。这条原则背后的原理是很显而易见的:你无法改变右值,因为对常量的引用确保程序不会通过这个接口改变右值。下面的例子,f()函数包含一个对常整型变量的引用。

1 void f(const int & i);
2 
3 int main()
4 {
5 f(2); /* OK */
6 }

这段代码将右值2”做为函数f()的一个参数。代码运行时,C++将创建一个值为2的临时整型变量并将其与引用类型i绑定。这个临时对象与它的接口将在 f()运行期间一直存到直到函数f返回。函数f返回后它们立即被释放。注意我们没有将i声明为常量类型,但是函数f仍有可能修改它的这个参数,这将引起异常。因此最好是将引用与常量类型绑定。

同样的规则适用于自定义类型。只有一个临时对象为常量时才可以与引用类型绑定。
struct A{};

1 void f(const A& a);
2 
3 int main()
4 {
5     f(A()); /* OK, binding a temporary A to a const reference*/
6 }

 

话题3:逗号表达式

逗号表达式是从C语言沿袭下来的。它就像你经常使用的for循环与while-loop循环一样。但是这里面的语法规则远不像看起来的那样。首先,让我们看看什么是逗号表达式。

一个表达式可以被逗号分隔为一个或若干个子表达式。例如:

1     if(++x, --y, cin.good()) /*three expressions*/

这条if语句被逗号分事为三个表达式。从C++的角度每个表达式都是合法的但是副作用产生了。整个逗号表达式的值是由最右边的表达式决定的。于是只有con.good()的返回值是true时整个表达式的值才是true。这里有另一个关于逗号表达式的例子。

1 int j=10;
2 int i=0;
3 
4 while( ++i, --j)
5 {
6     /*..repeat as long as j is not 0*/
7 }

     

话题4:在程序启动前调用函数

有些应用需要在主程序启运前运行启动函数。例如投票、支付和登录函数必须在实际种程序启动前运行。一个最简单的实现方法就是在一个全局对象的构造函数里调用这些函数。因为全局对象在程序的最开头被隐式的创建,这些函数就可以在main()函数之前得到运行。例如:

1 class Logger
2 {
3 public:
4     Logger()
5     {
6         activate_log();
7     }
8 };
9 
10 Logger log; /*global instance*/
11 
12 int main()
13 {
14     record * prec=read_log();
15     //.. application code
16 }

全局对象logmain()函数启动之前被创建。在它的构造函数里,log调用了active_log()函数。于是,当main()函数启动时,它可以从日志文件中读取数据。

posted on 2008-09-17 11:03 肥仔 阅读(177) 评论(0)  编辑 收藏 引用 所属分类: C++ 基础


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理