Making your C++ code robust

  • Validating Function Input 

      在函数设计的时候,对传入的参数进行检测是一直都推荐的。例如、如果你设计的函数是公共API的一部分,它可能被外部客户端调用,这样很难保证客户端传进入的参数就是正确的。

      例如,让我们来看看这个hypotethical DrawVehicle() 函数,它可以根据不同的质量来绘制一辆跑车,这个质量数值(nDrawingQaulity )是0~100。prcDraw 定义这辆跑车的轮廓区域。

      看看下面代码,注意观察我们是如何在使用函数参数之前进行参数检测:

BOOL DrawVehicle(HWND hWnd, LPRECT prcDraw, int nDrawingQuality)
  {
    // Check that window is valid
    if(!IsWindow(hWnd))
      return FALSE;
 
    // Check that drawing rect is valid
    if(prcDraw==NULL)
      return FALSE;
 
    // Check drawing quality is valid
    if(nDrawingQuality<0 || nDrawingQuality>100)
      return FALSE;
   
    // Now it's safe to draw the vehicle
 
    // ...
 
    return TRUE;
  }

  • Validating Pointers

       在指针使用之前,不检测是非常普遍的,这个可以说是我们引起软件崩溃最有可能的原因。如果你用一个指针,这个指针刚好是NULL,那么你的程序在运行时,将报出异常。

  CVehicle* pVehicle = GetCurrentVehicle();
  
  // Validate pointer
  if(pVehicle==NULL)
  {
    // Invalid pointer, do not use it!
    return FALSE;
  }

  • Initializing Function Output

     如果你的函数创建了一个对象,并要将它作为函数的返回参数。那么记得在使用之前把他复制为NULL。如不然,这个函数的调用者将使用这个无效的指针,进而一起程序错误。如下错误代码:

int CreateVehicle(CVehicle** ppVehicle)
  {
    if(CanCreateVehicle())
    {
      *ppVehicle = new CVehicle();
      return 1;
    }    
 
    // If CanCreateVehicle() returns FALSE,
    // the pointer to *ppVehcile would never be set!
    return 0;
  }

      正确的代码如下;

  int CreateVehicle(CVehicle** ppVehicle)
  {
    // First initialize the output parameter with NULL
    *ppVehicle = NULL;
 
    if(CanCreateVehicle())
    {
      *ppVehicle = new CVehicle();
      return 1;
    }    
 
    return 0;
  }

  • Cleaning Up Pointers to Deleted Objects

     在内存释放之后,无比将指针复制为NULL。这样可以确保程序的没有那个地方会再使用无效指针。其实就是,访问一个已经被删除的对象地址,将引起程序异常。如下代码展示如何清除一个指针指向的对象:

 // Create object
 CVehicle* pVehicle = new CVehicle();
 delete pVehicle; // Free pointer
 pVehicle = NULL; // Set pointer with NULL

你可能感兴趣的:(Making your C++ code robust)