为什么我应该使用CString的GetBuffer成员而不是SetAt?

时间:2016-11-16 00:04:52

标签: c++ mfc

我目前正在研究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()时。使用它有什么好处吗?

2 个答案:

答案 0 :(得分:2)

在上面的示例中,最好使用SetAt方法。

在某些情况下,您需要GetBuffer来直接访问缓冲区,主要是在与WinAPI函数一起使用时。例如,要将::GetWindowText与WinAPI代码一起使用,您需要按如下方式分配缓冲区:

int len = ::GetWindowTextLength(m_hWnd) + 1;
char *buf = new char[len];
::GetWindowText(m_hWnd, buf, len);
...
delete[] buf;

使用CWnd::GetWindowText(CString&)在MFC中可以完成同样的事情。但是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();
}

答案 1 :(得分:2)

除非您别无选择,否则请勿使用GetBuffer。正是因为(1)您已经知道的原因,必须遵循您可能忘记做的ReleaseBuffer,导致资源泄漏。 (2)您可能无意中对基础数据进行了更改,使其在某种程度上不一致。通常,函数GetString,SetString,GetAt和SetAt将满足您的需求并且没有任何缺点。喜欢他们。