您的位置:首页 > 编程语言

如何写优雅的代码(5)--不一样的类用法

2010-04-21 10:23 274 查看
//=====================================================================
//TITLE:
// 如何写优雅的代码(5)--不一样的类用法
//AUTHOR:
// norains
//DATE:
// Tuesday 20-April-2010
//Environment:
// Visual C++ 2005
//=====================================================================

作为本文的楔子,提出一个问题:如何计算程序运行时某个API函数的实际调用次数?再具体一点来说,有个大家都熟悉的API函数GetParent,我们如何统计它在我们代码中被调用的次数?

最简单的做法,可能大家都能想得出来,声明一个全局变量,在每次调用前都自增加一次。这个做法在调用函数次数比较少的情况下,的确无伤大雅;但如果是有上百处,是不是打算在这上百处前都添加一句自增的语句?更为糟糕的是,如果这个统计仅仅是在Debug时使用,正式发布时需要去掉,打算怎么弄?在编译之前手工删掉的方式我估计谁都不会用,估计大家都会想到宏定义,比如:
#ifdef _DEBUG
g_iCount ++;
#endif
hWndParent = GetParent(hWnd);


  看起来问题是解决了,但实际上引入的麻烦却不少:我们如何确定每次调用前都自增了一次?--特别是日后添加的调用代码,添加的人可能是自己,也可能是同事,如何保证会在调用之前还记得这个无关紧要的自增宏呢?
  
  这还不是最麻烦的,如果我们需要统计的函数不止一个,那么每增加一个统计如上的麻烦将增加一倍。我想,这是谁都无法接受的
  
  其实解决的方法很简单,C++不是有个函数的重载么?我们将GetParent直接重载不就可以了么?当然了,这个还有一个小小的限制,就是代码必须是以类为基础的。方法很简单,我们可以声明一个基类,然后在这个类里面重载GetParent,最后别的类派生于该类即可。
  
  根据此思想,我们声明一个基础类:
  
class CBaseFunc
{
public:
CBaseFunc(){}
virtual ~CBaseFunc(){}

private:
static HWND GetParent(HWND hWnd)
{
++ ms_dwCount;
return ::GetParent(hWnd);
}

private:
static DWORD ms_dwCount;
};

DWORD CBaseFunc::ms_dwCount = 0;


  
  我们其它类都继承于该类:
class CMonitor:
public CBaseFunc
{
public:
CMonitor(){};
virtual ~CMonitor(){};
};

  
  就是这么简单,我们不用担心忘记添加宏,不用麻烦地修整原来的代码,我们只需要一个基础类,一个不加::前缀的API函数调用,仅此而已。
  
  统计只不过是我们的一个应用,重载带来的好处并不仅限于此,我们可以在API函数调用前做太多事情,只要不缺乏想象力。
  
  比如说,CloseHandle这个API函数,我们都知道,如果同一句柄被重复关闭,那么会导致溢出。如果在执行前,我们能判断该句柄之前是否已经被关闭,而后才调用CloseHandle就好了。如果我们在基类中重载该函数,那么这也不是大问题:
  
  class CBaseFunc
  {
  public:
   CBaseFunc(){}
   virtual ~CBaseFunc(){}
  
  
  private:
   static BOOL CloseHandle(HANDLE hObject)
   {
    //IsCloseBefore是我们自己定义的一个检查句柄的函数
    if(IsCloseBefore(hObject) == FALSE)
    {
     return ::CloseHandle(hObject);
    }
    else
    {
     return FALSE;
    }
   }
  };
  


  
  也许有人看到这里会问,能不能不使用类,直接声明同名同形参的函数呢?答案是否定的,因为编译器会抱怨。
  
  函数重载,在很多时候,带给我们的惊喜远比想象的多。很多的解决方法,可以完全抛弃类;但使用类,却能带给我们更多的便捷,为什么我们还要拒绝它呢?
  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: