【问题标题】: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 时可能会导致内存泄漏() 不被调用。使用它有什么好处吗?

【问题讨论】:

    标签: c++ mfc


    【解决方案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 函数可以满足您的需要,而且没有缺点。更喜欢他们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-23
        • 2018-05-10
        • 2014-03-12
        • 2012-12-13
        • 2013-11-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多