许多Windows API采用指向缓冲区和大小元素的指针,但结果需要进入c ++字符串。 (我在这里使用windows unicode,所以它们是wstrings)
以下是一个例子: -
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
using namespace std;
// This is the method I'm interested in improving ...
wstring getComputerName()
{
vector<wchar_t> buffer;
buffer.resize(MAX_COMPUTERNAME_LENGTH+1);
DWORD size = MAX_COMPUTERNAME_LENGTH;
GetComputerNameW(&buffer[0], &size);
return wstring(&buffer[0], size);
}
int main()
{
wcout << getComputerName() << "\n";
}
我的问题是,这是编写getComputerName函数的最佳方法,以便更好地适应C ++,还是有更好的方法?除非我错过了什么,否则我没有看到任何方式直接使用字符串而不通过向量?它工作正常,但不知何故看起来有点难看。问题不在于特定的API,它只是一个方便的例子。
答案 0 :(得分:7)
在这种情况下,我没有看到std :: vector为派对带来了什么。 MAX_COMPUTERNAME_LENGTH可能不是很大,所以我只想使用C风格的数组作为临时缓冲区。
答案 1 :(得分:3)
请参阅this answer其他问题。它为StringBuffer类提供了源代码,它可以非常干净地处理这种情况。
答案 2 :(得分:2)
我想说,既然你已经完成了在更通用的C ++接口背后提取Windows API的任务,那就完全废除了vector,并且不要为wstring构造函数而烦恼:
wstring getComputerName()
{
wchar_t name[MAX_COMPUTERNAME_LENGTH + 1];
DWORD size = MAX_COMPUTERNAME_LENGTH;
GetComputerNameW(name, &size);
return name;
}
此函数将返回有效的wstring对象。
答案 3 :(得分:1)
我会使用矢量。在回答你说你选择了一个不好的例子时,假装我们在字符串长度上没有合理的恒定上限。然后它就不那么容易了:
#include <string>
#include <vector>
#include <windows.h>
using std::wstring;
using std::vector;
wstring getComputerName()
{
DWORD size = 1; // or a bigger number if you like
vector<wchar_t> buffer(size);
while ((GetComputerNameW(&buffer[0], &size) == 0))
{
if (GetLastError() != ERROR_BUFFER_OVERFLOW) aargh(); // handle error
buffer.resize(++size);
};
return wstring(&buffer[0], size);
}
在实践中,你可能可以通过写入字符串来逃避,但我并不完全确定。除了标准中的内容之外,你当然还需要std::wstring
实现的额外保证,但我希望MSVC的字符串可能正常。
我认为,如果wstring::reference
为wchar_t&
,那么您就会排序。 21.3.4定义非const operator[]
返回reference
,并返回data()[pos]
。因此,如果reference
只是一个普通的wchar_t&
,那么通过引用就没有令人兴奋的写时复制行为的范围,并且字符串实际上必须可以通过指针&buffer[0]
进行修改。我认为。这里的基本问题是标准允许实现更灵活,而不是需要它。
虽然这是很多努力和评论,只是为了避免复制字符串,所以我从来没有觉得需要避免使用中间数组/向量。