邀朋友种豆,一起分享吧
喜欢购买正品行货?那就去品牌街

跟着示例学CString中GetBuffer与ReleaseBuffer

来自:种豆 时间:2017-12-29 阅读:3341次 原文链接

    先看一个典型的GetBuffer与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.ReleaseBuffer(); //千万不能缺少
  fclose(fp);
}

    上面的函数是GetBuffer函数最典型的用法了,其实它就相当于申请一块nLen大小的内存,只不过,这块内存是被引用在CString对象的内部而已,这是非常有效的一种用法,如果不直接用GetBuffer函数来申请的话,那么你必须用new操作符(或者malloc()函数)在CString的外部申请,然后再将申请的内存拷贝到CString对象中,显然这是一个非常冗余的操作,会使你函数的效率大大下降。

    ReleaseBuffer函数是用来告诉CString对象,你的GetBuffer所引用的内存已经使用完毕,现在必须对它进行封口,否则 CString将不会知道它现在所包含的字符串的长度,所以在使用完GetBuffer之后,必须立即调用ReleaseBuffer函数重置 CString的内部属性,其实也就是头部信息。

    GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能。

再看一段ReleaseBuffer调用的示例:

CString s="hello";   
LPTSTR ps=s.GetBuffer();
strcpy(ps,"hi");    
s.ReleaseBuffer();

    此时调用s.GetLength()获取的值是2,正确无误。但如果注释掉s.ReleaseBuffer()这一行,s.GetLength()获取的值则是5,错了。

    我们来看看MFC中ReleaseBuffer的代码:

void ReleaseBuffer( int nNewLength = -1 )
{
  if( nNewLength == -1 )
  {
     nNewLength = StringLength( m_pszData );
  }
  SetLength( nNewLength );
}

    很明显ReleaseBuffer的作用就是更新字符串的长度。CString内,GetLength获取字符串长度并不是动态计算的,而是在赋值操作后计算并保存在一个int变量内的,当通过GetBuffer直接修改CString时,那个int变量并不会自动更新,于是便有了 ReleaseBuffer。   

    其实,计算长度还能用strlen(),这个就算不调用ReleaseBuffer也不会出错,但如果不ReleaseBuffer,CString对象在以后的代码中将不能实现长度自适应增长的功能。

    是否需要在GetBufer后面调用ReleaseBuffer(),是根据你的后面的程序是否需要继续使用该字符串变量,并且是否动态改变其长度而定的。如果你GetBuffer以后程序自函数就退出,局部变量都不存在了,可以不调用ReleaseBuffer。

 

 
关于种豆 ┊ 联系我们 ┊ 免责声明 ┊ 发帖须知 ┊ 请提意见 ┊ 站点地图
本站为个人爱好兴趣分享网站,不代表本人观点,如有侵权请联系QQ3033380280进行处理
sowsoy.com 版权所有 Copyright©2010-2021 备案号:蜀ICP备2020025376号-3
Email:sowsoy#hotmail.com