1,《高质量C++/C 编程指南》第5章第4节讲到类中的常量时,作者是推荐用enum来实现

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成员来实现:

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

BYTE *pBuffer = new BYTE[len];
if (pBuffer == NULL)
{
//分配内存失败
    delete [] pBuffer;
    pBuffer 
= NULL; //防止成为“野指针”
    return;
}
//end of if

4,如果函数的参数是一个指针,则不要指望用该指针去申请动态内存,下面示例中str依旧是NULL.原因在于调用函数时总是会为每个参数制作临时副本,指针也不例外,因此GetMemory里申请了内存,只是把str指针的副本所指的内存地址改变了,但str本身没变。而每执行一次GetMemory就会泄露一块内存,因为那个副本指针指向的内存没有free

void GetMemory(char *p, int num)
{
    p 
= (char*) malloc(sizeof(char* num);
}

int main()
{
    
char *str = NULL;
    GetMemory(str, 
100);
    strcpy(str, 
"hello world");
    
return 0;
}

可以改成如下:

void GetMemory(char **p, int num)
{
    
*= (char*) malloc(sizeof(char* num);
}

int main()
{
    
char *str = NULL;
    GetMemory(
&str, 100);
    strcpy(str, 
"hello world");
    cout 
<< str <<endl;
    free(str);
    str 
= NULL;
    
return 0;
}

5,在客户现场测试时发现ActiveX控件加载运行后,出现内存泄露的问题,几番测试后发现是是调用 CxImage库的Encode方法时犯了个错误,没有释放图像数据缓冲区,修改后代码如下:

CString Scan::EncodeImage()
{
//对生成的图片进行Base64编码
    ZBase64 zBase;
    
//图片编码
    CxImage  image;   // 定义一个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;
    }
//返回编码后的图片数据
    CString result;
    result 
= strTmpResult.c_str();
    
return result;
}

6,《C++标准程序库》第6章第5节,运行时指定排序准则。

#include <iostream>
#include 
<set>
using namespace std;

template 
<class T>
class RuntimeCmp
{
public:
    
enum cmp_mode {NORMAL,REVERSE};
private:
    cmp_mode mode;
public:
    RuntimeCmp(cmp_mode m 
= 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::iterator iter;
    
for (iter = set.begin(); iter != set.end(); ++iter)
    {
        cout 
<< *iter << endl;
    }
}
int main()
{
    IntSet coll1;
    fill(coll1);
    PrintElements(coll1);

    RuntimeCmp
<int> reverse_order(RuntimeCmp<int>::REVERSE);

    IntSet coll2(reverse_order);
    fill(coll2);
    PrintElements(coll2);

    coll1 
= coll2;
    coll1.insert(
3);
    PrintElements(coll1);

    
if (coll1.value_comp() == coll2.value_comp())
    {
        cout 
<< "same sorting criterion" << endl;
    }
    
return 0;
}
 

7,我讨厌C++有两个原因,一个是字符串,一个是内存泄漏。这不,今天又犯了一个错误,复审代码时,读到下面的AllocSysString()时,需要调用方用SysFreeString来释放,而ActiveX控件嵌入IE后,在JavaScript代码中又该如何释放呢?

BSTR CCardScanCtrl::GetName(void)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    CString strResult;
    strResult 
= Scan::getInstance().m_strName;
    
return strResult.AllocSysString();
}
  于是,改为如下代码:
BSTR CCardScanCtrl::GetName(void)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    CString strResult;
    strResult 
= Scan::getInstance().m_strName;
    CComBSTR bstrResult(strResult);
    
return bstrResult;
}

可是,这样的后果是在JavaScript中访问Name属性时,出现内存访问错误的bug,原因就是CComBSTR的析构函数:

~CComBSTR() 

::SysFreeString(m_str); 
}