1,《高质量C++/C 编程指南》第5章第4节讲到类中的常量时,作者是推荐用enum来实现
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> class MyClass { public : MyClass() { for ( int i = 0 ;i < SIZE; ++ i) { array[i] = i + 1 ; } } void PrintArray() { for ( int i = 0 ;i < SIZE; ++ i) { cout << array[i] << endl; } } private : enum {SIZE = 100 }; int array[SIZE]; };但我个人更喜欢用static const成员来实现:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> class MyClass { public : MyClass() { for ( int i = 0 ;i < SIZE; ++ i) { array[i] = i + 1 ; } } void PrintArray() { for ( int i = 0 ;i < SIZE; ++ i) { cout << array[i] << endl; } } private : static const int SIZE = 100 ; int array[SIZE]; };2,不要将正常值和错误标志混在一起返回,正常值用输出参数获得,错误标志用return语句返回。
3,在使用内存前检查指针是否为NULL
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> BYTE * pBuffer = new BYTE[len]; if (pBuffer == NULL) { // 分配内存失败 delete[]pBuffer; pBuffer = NULL; // 防止成为“野指针” return ; } // endofif4,如果函数的参数是一个指针,则不要指望用该指针去申请动态内存,下面示例中str依旧是NULL.原因在于调用函数时总是会为每个参数制作临时副本,指针也不例外,因此GetMemory里申请了内存,只是把str指针的副本所指的内存地址改变了,但str本身没变。而每执行一次GetMemory就会泄露一块内存,因为那个副本指针指向的内存没有free。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> void GetMemory( char * p, int num) { p = ( char * )malloc( sizeof ( char ) * num); } int main() { char * str = NULL; GetMemory(str, 100 ); strcpy(str, " helloworld " ); return 0 ; }可以改成如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> void GetMemory( char ** p, int num) { * p = ( char * )malloc( sizeof ( char ) * num); } int main() { char * str = NULL; GetMemory( & str, 100 ); strcpy(str, " helloworld " ); cout << str << endl; free(str); str = NULL; return 0 ; }5,在客户现场测试时发现ActiveX控件加载运行后,出现内存泄露的问题,几番测试后发现是是调用 CxImage库的Encode方法时犯了个错误,没有释放图像数据缓冲区,修改后代码如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> CStringScan::EncodeImage() { // 对生成的图片进行Base64编码 ZBase64zBase; // 图片编码 CxImageimage; // 定义一个CxImage对象 image.Load( this -> m_strImgPath,CXIMAGE_FORMAT_JPG); // 先装载jpg文件,需要指定文件类型 long size = 0 ; // 得到图像大小 BYTE * buffer = 0 ; // 存储图像数据的缓冲 image.Encode(buffer,size,CXIMAGE_FORMAT_JPG); // 把image对象中的图像以type类型数据copy到buffer string strTmpResult = zBase.Encode(buffer,size); // 对生成的图片进行Base64编码 if (buffer != NULL) { // 释放缓冲区 delete[]buffer; buffer = NULL; } // 返回编码后的图片数据 CStringresult; result = strTmpResult.c_str(); return result; }6,《C++标准程序库》第6章第5节,运行时指定排序准则。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> #include < iostream > #include < set > using namespace std; template < class T > class RuntimeCmp { public : enum cmp_mode{NORMAL,REVERSE}; private : cmp_modemode; public : RuntimeCmp(cmp_modem = NORMAL):mode(m) { } bool operator ()( const T & t1, const T & t2) { return mode == NORMAL ? t1 < t2:t2 < t1; } bool operator == ( const RuntimeCmp & rhs) { return mode == rhs.mode; } }; typedef set < int ,RuntimeCmp < int > > IntSet; void fill(IntSet & set ) { set .insert( 4 ); set .insert( 7 ); set .insert( 5 ); set .insert( 1 ); set .insert( 6 ); set .insert( 2 ); set .insert( 5 ); } void PrintElements(IntSet & set ) { IntSet::iteratoriter; for (iter = set .begin();iter != set .end(); ++ iter) { cout << * iter << endl; } } int main() { IntSetcoll1; fill(coll1); PrintElements(coll1); RuntimeCmp < int > reverse_order(RuntimeCmp < int > ::REVERSE); IntSetcoll2(reverse_order); fill(coll2); PrintElements(coll2); coll1 = coll2; coll1.insert( 3 ); PrintElements(coll1); if (coll1.value_comp() == coll2.value_comp()) { cout << " samesortingcriterion " << endl; } return 0 ; }
7,我讨厌C++有两个原因,一个是字符串,一个是内存泄漏。这不,今天又犯了一个错误,复审代码时,读到下面的AllocSysString()时,需要调用方用SysFreeString来释放,而ActiveX控件嵌入IE后,在JavaScript代码中又该如何释放呢?
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> BSTRCCardScanCtrl::GetName( void ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CStringstrResult; strResult = Scan::getInstance().m_strName; return strResult.AllocSysString(); } 于是,改为如下代码: <!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> BSTRCCardScanCtrl::GetName( void ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CStringstrResult; strResult = Scan::getInstance().m_strName; CComBSTRbstrResult(strResult); return bstrResult; }可是,这样的后果是在JavaScript中访问Name属性时,出现内存访问错误的bug,原因就是CComBSTR的析构函数:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> ~ CComBSTR() { ::SysFreeString(m_str); }