手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

高质量C /C编程指南 -- 第11章 其他编程经验

来源:互联网 作者:west263.com 时间:2008-02-23
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
11.1 使用const提高函数的健壮性
看到const关键字,C 程式员首先想到的可能是const常量。这可不是良好的条件反射。假如只知道用const定义常量,那么相当于把火药仅用于制作鞭炮。const更大的魅力是他能够修饰函数的参数、返回值,甚至函数的定义体。

const是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,能够预防意外的变动,能提高程式的健壮性。所以很多C 程式设计书籍建议:“Use const whenever you need”。

11.1.1 用const修饰函数的参数

假如参数作输出用,不论他是什么数据类型,也不论他采用“指针传递”还是“引用传递”,都不能加const修饰,否则该参数将失去输出功能。

const只能修饰输入参数:

u 假如输入参数采用“指针传递”,那么加const修饰能够防止意外地改变该指针,起到保护作用。

例如StringCopy函数:

void StringCopy(char *strDestination, const char *strSource);

其中strSource是输入参数,strDestination是输出参数。给strSource加上const修饰后,假如函数体内的语句试图改变strSource的内容,编译器将指出错误。

u 假如输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const修饰。

例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A为用户自定义的数据类型。

u 对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。

为了提高效率,能够将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,无需产生临时对象。但是函数void Func(A &a) 存在一个缺点:“引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。

以此类推,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也很快,“值传递”和“引用传递”的效率几乎相当。

问题是如此的缠绵,我只好将“const &”修饰输入参数的用法总结一下,如表11-1-1所示。

对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。



对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。


表11-1-1 “const &”修饰输入参数的规则

11.1.2 用const修饰函数的返回值

u 假如给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。

例如函数

const char * GetString(void);

如下语句将出现编译错误:

char *str = GetString();

正确的用法是

const char *str = GetString();

u 假如函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。

例如不要把函数int GetInt(void) 写成const int GetInt(void)。

同理不要把函数A GetA(void) 写成const A GetA(void),其中A为用户自定义的数据类型。

假如返回值不是内部数据类型,将函数A GetA(void) 改写为const A & GetA(void)的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就能够了,否则程式会出错。见6.2节“返回值的规则”。

u 函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。

例如

class A

{…

A & operate = (const A &other); // 赋值函数

};

A a, b, c; // a, b, c 为A的对象

a = b = c; // 正常的链式赋值

(a = b) = c; // 不正常的链式赋值,但合法

假如将赋值函数的返回值加const修饰,那么该返回值的内容不允许被改变。上例中,语句 a = b = c仍然正确,但是语句 (a = b) = c 则是非法的。



[1] [2] 下一页

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

热点关注
IDC资讯 虚拟主机 域名注册 托管租用 vps主机 智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 价格总览 | 资讯中心 | 友情链接 | 网站地图 | 招贤纳士 | RSS