【问题标题】:Should CString's GetBufferSetLength() have a matching ReleaseBuffer() call?CString 的 GetBufferSetLength() 是否应该有一个匹配的 ReleaseBuffer() 调用?
【发布时间】:2017-01-09 13:23:49
【问题描述】:

根据 CString 的 GetBufferSetLength() 的 MSDN 文档,对该方法的调用之后应该是对 ReleaseBuffer() 的匹配调用。

但是,在同一页面的示例代码中,有一条注释指出调用ReleaseBuffer()不必要的

CSimpleString str(pMgr);
LPTSTR pstr = str.GetBufferSetLength(3);
pstr[0] = _T('C');
pstr[1] = _T('u');
pstr[2] = _T('p');

// No need for trailing zero or call to ReleaseBuffer()
// because GetBufferSetLength() set it for us.

str += _T(" soccer is best!");
ASSERT(_tcscmp(str, _T("Cup soccer is best!")) == 0);

那么,正确的代码应该在GetBufferSetLength() 之后调用ReleaseBuffer(),还是不需要调用?


编辑

根据我所做的一些测试,听起来在GetBufferSetLength() 之后调用ReleaseBuffer() 是不必要的,但是:

  1. 这些测试尚未完成。
  2. 我有兴趣根据 CString 的接口官方规范编写正确代码,而不是可能在给定版本的 VS 上工作然后在下一个版本上失败的依赖于实现的代码。

【问题讨论】:

  • 你真的需要使用这个糟糕的库(MFC/ATL)吗?
  • @SergeyA:请保持话题 :) 是的,有很多 C++ 项目使用这些库。
  • 全面披露 - 是我支持你的问题;)。是的,我相信,出于多种原因停止使用它们是有充分理由的。
  • @PaulMcKenzie:是的,std::wstring::resize() 更简单、更清晰 :) 但老实说用std::wstring 操作然后复制回CString 似乎有点过头了。
  • @Mr.C64 -- 您的编辑中的点号2. 说明了我的观点。这些据说是“有据可查”的功能,但它们是吗?我猜不是,因为你在问如何使用它们。一旦到了那个阶段,实现就真的很糟糕(用户不会弄清楚如何安全地使用公共接口)。

标签: c++ string mfc atl


【解决方案1】:

ReleaseBuffer 的目的是将缓冲区包含的 C 样式字符串的状态与 CString 内部变量的状态同步。大概这只是获取最终的字符串长度并将其存储在内部,如果存在很大差异,可能会重新分配缓冲区。

在示例的情况下,字符串长度被声明为正好是 3 个字符。由于字符串的大小没有通过对缓冲区的操作而改变,因此无需在操作后更新长度。

【讨论】:

    【解决方案2】:

    CSimpleStringT::GetBufferSetLength 的文档非常清楚:

    如果您使用CSimpleStringT::GetBufferSetLength 返回的指针来更改字符串内容,请在使用任何其他 之前调用ReleaseBuffer 来更新CSimpleStringT 的内部状态CSimpleStringT 方法。

    示例代码不是合同性的。如果示例代码与正式规范相矛盾,请使用正式规范。正式的规范是契约性的。


    注意:在不遵循记录协议的情况下使用时,实现不需要失败。因此,您无法测试是否需要该协议的所有步骤。

    【讨论】:

    • 但是包含的示例代码在注释中明确指出了 相反 ("// 不需要尾随零或调用 ReleaseBuffer() 因为 GetBufferSetLength() 设置它是给我们的。”),所以整个文档不清楚。要么段落中存在错误,要么代码 sn-p 注释中存在错误。
    • @Mr.C64:示例代码从不合同。它可能在某些时候是正确的,但从未更新。重要的是散文。
    • 很难想象您会调用GetBufferSetLength 并且 更改字符串内容的情况。我想知道他们是否真的想说“字符串长度”而不是“字符串内容”?
    • 我当然不能争论这一点,我只是想大声地想知道它是否不仅仅是文档中的一个错误。这不是第一次发生这种情况——例如,微软的文档没有经过 C++ 标准所获得的严格审查。编写文档的人几乎肯定不是对类行为负责的人。
    • @MarkRansom:尽管 MFC 文档的质量始终低于 Windows API 文档,但我仍然认为该措辞是有意识地选择的。可以详细说明特殊情况,在这种情况下调用ReleaseBuffer 不是严格要求的。这只允许开发人员编写 "clever" 代码,偶尔会省略对ReleaseBuffer 的调用。它既难以阅读,又不必要地限制了CString 类的未来发展。相反,规范使事情变得简单,以换取偶尔(技术上)多余的调用。
    猜你喜欢
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多