为啥我应该使用 CString 的 GetBuffer 成员而不是 SetAt?
Posted
技术标签:
【中文标题】为啥我应该使用 CString 的 GetBuffer 成员而不是 SetAt?【英文标题】:Why should I use GetBuffer member of CString instead of SetAt?为什么我应该使用 CString 的 GetBuffer 成员而不是 SetAt? 【发布时间】:2016-11-16 00:04:52 【问题描述】:我目前正在研究 MFC 库,我想知道为什么我应该使用 GetBuffer 成员,它返回指向 CString 对象缓冲区的指针,而不是其他允许读取和更改该对象中字符的成员函数? 例如为什么我应该这样做(代码更改 CString 对象的第一个字符):
CString aString(_T("String")); //new CString object
LPTSTR p = aString.GetBuffer(); //create new pointer to aString buffer
_tcsncpy(p, LPCTSTR(_T("a")), 1); //set first character to 'a'
aString.ReleaseBuffer(); //free allocated memory
代替:
CString aStr(_T("String")); //new CString object
aStr.SetAt(0, _T('a')); //set character at 0 position to 'a'
我想有一个更合适的应用程序使用 GetBuffer() 成员,但我不知道它可以是什么......这个函数需要 ReleaseBuffer() 来释放内存,我在 ReleaseBuffer 时可能会导致内存泄漏() 不被调用。使用它有什么好处吗?
【问题讨论】:
【参考方案1】:在上面的例子中,最好使用SetAt
方法。
在某些情况下,您需要GetBuffer
直接访问缓冲区,主要是在与 WinAPI 函数一起使用时。例如,要将::GetWindowText
与 WinAPI 代码一起使用,您需要按如下方式分配缓冲区:
int len = ::GetWindowTextLength(m_hWnd) + 1;
char *buf = new char[len];
::GetWindowText(m_hWnd, buf, len);
...
delete[] buf;
在 MFC 中使用CWnd::GetWindowText(CString&)
可以完成相同的操作。但是 MFC 必须通过GetBuffer
使用相同的基本 WinAPI 函数。 MFC对CWnd::GetWindowText
的实现大致如下:
void CWnd::GetWindowText(CString &str)
int nLen = ::GetWindowTextLength(m_hWnd);
::GetWindowText(m_hWnd, str.GetBufferSetLength(nLen), nLen+1);
str.ReleaseBuffer();
【讨论】:
【参考方案2】:除非您别无选择,否则不要使用GetBuffer
。正是因为(1)你已经知道的原因,它必须跟着ReleaseBuffer
,你可能会忘记这样做,导致资源泄漏。并且 (2) 您可能会无意中对底层数据进行更改,从而使其以某种方式不一致。通常情况下,GetString、SetString、GetAt 和 SetAt 函数可以满足您的需要,而且没有缺点。更喜欢他们。
【讨论】:
以上是关于为啥我应该使用 CString 的 GetBuffer 成员而不是 SetAt?的主要内容,如果未能解决你的问题,请参考以下文章
刚开始学C++,想请教高手们一下,将CString类型字符串转换为unsigned char型字符数组的转化方式