1、定义
CString::GetBuffer有两个重载版本:
(1)LPTSTR GetBuffer( );
(2)LPTSTRGetBuffer( int nMinBufLength );throw( CMemoryException );
调用第二个版本中,当设定的长度nMinBufLength小于原字符串长度nOldLen时,nMinBufLength默认等于原来字符串长度nOldLen,所以该参数会被忽略,不分配内存,指向原CString;当设定的长度大于原字符串本身的长度时就要重新分配(reallocate)一块比较大的空间出来。而调用第一个版本时,直接当做nMinBufLength=0。注意:nMinBufLength不包含最后结束的空字符。
参考:http://msdn.microsoft.com/en-us/library/aa314880(v=vs.60).aspx
2、作用
GetBuffer(int nMinBufLength)是用来返回一个你所指定大小可写内存的成员方法。它和被重载的操作符LPCTSTR还是有点本质区别的,LPCTSTR是直接返回一个只读内存的指针,而GetBuffer则是返回一个可以供调用者写入的内存,并且你可以给定大小。例如:
CString s("abcd");
LPTSTR p = s.GetBuffer( 10 );
strcpy( (char*)p, "Hello" ); // directly access CString buffer
s.ReleaseBuffer( );
cout << "CString s = "<< s ; //在多字节字符集_MBCS下面输出Hello
3、与ReleaseBuffer的结合使用
GetBuffer()主要作用是将字符串的缓冲区长度锁定,ReleaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能。
至于是否需要在GetBufer后面调用ReleaseBuffer(),是根据你的后面的程序是否需要继续使用该字符串变量,并且是否动态改变其长度而定的。如果你GetBuffer以后程序自函数就退出,局部变量都不存在了,调用不调用ReleaseBuffer没什么意义了;如果需要继续使用该字符串变量,则需要在使用之前调用ReleaseBuffer。
举个例子:
int readFile(CString& str, const CString& strPathName)
{
FILE* fp = fopen(strPathName, "r"); // 打开文件
fseek(fp, 0, SEEK_END); //指向文件尾部
int nLen = ftell(fp); //获得文件长度
fseek(fp, 0, SEEK_SET); //重置读指针
char* psz = str.GetBuffer(nLen); //分配足够内存
fread(psz, sizeof(char), nLen, fp); //读文件内容并写入str
str.ReleaseBuffer(); //千万不能缺少
fclose(fp);
}
上面的函数是GetBuffer函数最典型的用法了,其实它就相当于申请一块nLen大小的内存,只不过,这块内存是被引用在CString对象的内部而已,这是非常有效的一种用法,如果不直接用GetBuffer函数来申请的话,那么你必须用new操作符(或者malloc()函数)在CString的外部申请,然后再将申请的内存拷贝到CString对象中,显然这是一个非常冗余的操作,会使你函数的效率大大下降。
ReleaseBuffer函数是用来告诉CString对象,你的GetBuffer所引用的内存已经使用完毕,现在必须对它进行封口,否则 CString将不会知道它现在所包含的字符串的长度,所以在使用完GetBuffer之后,必须立即调用ReleaseBuffer函数重置 CString的内部属性,其实也就是头部信息。