编写高质量代码:改善C++程序的150个建议(连载5)

发表于:2012-4-09 10:02

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:李健    来源:51Testing软件测试网采编

  建议8:拒绝晦涩难懂的函数指针

  在C/C++程序中,数据指针是最直接也是最常用的,理解起来也相对简单容易,但是函数指针理解起来却并不轻松。函数指针在运行时的动态调用中应用广泛,是一种常见而有效的手段。但是,如果不注重一定的使用技巧,函数指针也会变得晦涩难懂。

  告诉我下面定义的含义是什么?

void (*p[10]) (void (*)());

  如此繁琐的语法定义几乎难以辨认,这与我们提倡的可读性背道而驰了。这样的函数指针之所以让程序员发愁,最主要的原因是它的括号太多了,往往会让程序员陷在括号堆中理不清头绪。下面一层一层地来分析吧。第一个括号中的*p[10]是一个指针数组,数组中的指针指向的是一些函数,这些函数参数为void (*)(),返回值为空;参数部分的void (*)()是一个无参数、返回值为空的函数指针。

  分析这样的代码简直是一种折磨。如何有效地提高函数指针定义的可读性呢?那就是使用typedef。typedef 方法可以有效地减少括号的数量,可以通过typedef来合理地简化这些声明,理清层次,所以它的使用倍受推荐。

  以上面的定义为例。首先,声明一个无参数、返回空的函数指针的typedef,如下所示:

typedef void (*pfv)();

  接下来,声明另一个typedef,一个指向参数为pfv且返回为空的函数指针:

typedef void (*pFun_taking_pfv) (pfv);

  现在,再去声明一个含有10个这样指针的数组就变得轻而易举了,而且可读性有了很大的提升:

typedef void (*pFun_taking_pfv) (pfv);

  现在,再去声明一个含有10个这样指针的数组就变得轻而易举了,而且可读性有了很大的提升:

pFun_taking_pfv p[10]; /*等同于void (*p[10]) (void (*)());*/

  请记住:

  函数指针在运行时的动态调用(例如函数回调)中应用广泛。但是直接定义复杂的函数指针会由于有太多的括号而使代码的可读性下降。使用typedef可以让函数指针更直观和易维护。拒绝晦涩难懂的函数指针定义,拒绝函数定义中成堆的括号。

  建议9:防止重复包含头文件

  假设,我们的工程中有如下三个文件:a.h、b.h和c.cpp,其中b文件中包含了a.h,c文件中又分别包含了a.h和b.h两个文件,如图1-1所示。

图1-1 工程文件示例

  在编译整个工程时,编译器会出现“multiple definition of”错误。原因在于a.h文件被包含了两次。为了避免同一个文件被包含多次,C/C++中有两种处理方式,一种是#ifndef方式,另一种是#pragma once方式。

  方式1:

  1. #ifndef __SOMEFILE_H__  
  2. #define __SOMEFILE_H__  
  3. ... ... // 声明、定义语句  
  4. #endif

  方式2:

  1. #pragma once  
  2. ... ... // 声明、定义语句

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号