首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

举例介绍 C++高质量编程 2

举例介绍 C++高质量编程 2

解析:
在循环中,当参数数组a中的某一个值为0时,将会产生除0异常,那么,这将会导致你在上面为m_pPtr申请的内存不能合理的释放。为了解决这个问题,我们写了一个auto_array作为卫兵来看守企图逃逸的指针。在auto_array对象PtrGuard析构的时候它会同时删除附加在它身上的内存指针。我们首先用PtrGuard来进行所有的指针操作,在确定操作完全结束的最后,把指针再赋给真正的变量,并使PtrGuard放弃对该指针的附加,这样我们就得到了一个最安全的结果。另外需要注意的是,C++的STL库里本来有一个和auto_array功能非常相似的模版类auto_ptr,但是它只支持单个对象的内存,不支持数组,写这样一个auto_array也是不得已而为之。
四、你需要开辟一段内存来存放和管理一个4 x 4的矩阵,并单位化之。
不合理:
    int aMatrix[4][4];   
  • for ( int i = 0; i < 4; i++ )   {   
  • for ( int j = 0; j < 4; j++ )   {   
  • if ( i == j )   {   
  • aMatrix[j] = 1;   }   
  • else   {   
  • aMatrix [j] = 0;   }   
  • }   
  • } 
合理:
    int aMatrix[4 * 4];   
  • for ( int i = 0; i < 4; i++ )   {   
  • for ( int j = 0; j < 4; j++ )   {   
  • if ( i == j )    {   
  • aMatrix[ i * 4 + j ] = 1;   }   
  • else   {   
  • aMatrix [ i * 4 + j ] = 0;   }   
  • }   
  • }   
解析: 
在任何时候都要避免使用多维数组,数组维数的增加,相应的程序复杂度将会以几何级数的方式增加,也更加的难于理解。
五、你需要对上面那个矩阵赋值,使它从左上角向右下角按先纵后横的顺序给它赋值
不合理:
    for( int i = 0; i < 4; i++ )   
  • {   for ( int j = 0; j < 4; j++ )   
  • {   aMatrix[ j * 4 + i ] = i * 4 + j;   
  • }   
  • }   
合理:
    for( int i = 0; i < 4; i++ )   
  • {   for ( int j = 0; j < 4; j++ )   
  • {   aMatrix[i * 4 + j ] = j * 4 + i;   
  • }   
  • }
解析:
尽量保证顺序的访问数组的每一个元素。由于Windows内存的管理模式,内存是分页管理的。顺序访问数组可以基本保证页面不会来回切换,从而减少了页失效的数量,提高了程序的整体性能。这种性能的提升对于大的数组尤为明显。
六、你需要用3个float值来表示一个三维的点,并要写一个函数对一个三维点的数组进行计算赋值。 
不合理:
    void foo( float *pPoints[3] )   
  • {   float aPoint[3] = { 1.0f, 2.0f, 3.0f };   
  • int nCount = (int)_msize( pPoints );   for ( int i = 0; i < nCount; i++ )   
  • {   pPoints[0] = aPoint[0];   
  • pPoints[1] = aPoint[1];   pPoints[2] = aPoint[2];   
  • }   
  • }
合理:
    struct POINT3   
  • {   float x, y, z;   
  • };   void foo( POINT3 *pPoints, int nCount )   
  • {   POINT3 Pt = { 1.0f, 2.0f, 3.0f };   
  • for ( int i = 0; i < nCount; i++ )   {   
  • pPoints = Pt;  }   
  • }
解析:
一,不要使用_msize对数组的大小进行测定,_msize只能对使用malloc或calloc申请的内存进行大小测定,对于其它的如new或一些API,将会导致程序的崩溃。在设计此类需要传入数组的函数时,别忘了把数组的元素数量也做为参数一并传入,哪怕它是固定的,这将是一个良好的习惯。
二,对于float[3]这种类型,尽量避免直接使用它,最好的办法就是用struct对其进行简单的封装,在复制的时候直接使用“=”就可以进行准确的按位赋值了。
七、你有一个函数的定义,在这个函数中会new一个比较大的对象Data,并在计算后将它删除。但这个函数将被频繁调用。
不合理:
    void foo( void )   
  • {   Data *p = new Data;   
  • CalcData( p );   delete p;   
  • }  
合理:
    char Buf[sizeof(DATA)];   
  • void foo( void )   {   
  • Data *p = new(Buf) Data;   CalcData( p );   
  • }  
解析:
new(buf) type;是定位的new语法,它不会真正的分配内存,而是简单的在指定的已分配的内存起点上划分出一段与类型大小匹配的空间,并直接在这段内存上对该类型进行构造对象,并返回对象的指针。由于它没有真正的分配内存空间,因此它的效率是非常高的,在类似于上述例程中,频繁申请和释放一个大对象的操作,定位的new可以带来很大的效率提升。
返回列表