我们可以用std::string交换char*吗
Can we swap char* with std::string
修改std::string::op[]的结果合法吗?
我想交换char*和std::string的内容,但无法完成。经过上面的链接,我仍然无法得到问题的答案。
这就是我正在尝试做的,但无法成功地用char*交换字符串。该代码已在VS2010上验证。
更新1所有的努力都是看看我是否能获得任何性能而不获得任何SO分数。:-)
更新2我在评论中提到了我打算这么做的原因。人们还认为这需要暂停吗?
void Swap(char* const& left, char* const& right)
{
std::swap(const_cast<char*>(left), const_cast<char*>(right));
}
std::string ToString()
{
std::string ret(1, ' ');
char* str = new char[6]();
strcpy(str, "Jagan");
Swap(&ret[0], str);
return ret;
}
无法完成。
std::string
没有为您提供替换其内部数据指针的标准方法。
事实上,并不是所有std::string
的实现都总是有一个指向使用new[]
分配的零终止字符块的指针。你不应该知道,如果你发现了,当然也不应该依赖它(信息隐藏/实现隐藏)。
不同的std::string
实现可能会执行以下任何操作:
- 保持大小与非零端接的CCD_ 5分开。除了经典的C字符串之外,
std::string
的实例还允许包含null字符 - 但在具有参考计数的不同
std::strings
之间共享。你不想干涉这里 - 具有一个分配给
char [16]
的堆栈,该堆栈用于短字符串,而不是堆指针
这就是为什么当你想与自己管理的char*
交换时,你不得不复制std::string
的内容。
代码&ret[0]
所做的只是创建一个临时变量,该变量是指向ret
中字符的指针。对swap
的调用将该临时变量设置为指针str
,并将str
设置为该临时变量。结果是ret
不受影响,并且您泄漏了str
中的内存。为了更清楚,这个代码相当于
char* str = new char[6]();
strcpy(str, "Jagan");
char* tmpPtr = &ret[0]
Swap(tmpPtr, str);
所以你可以在它的末尾看到tmpPtr
等于str
的原始值。您根本无法访问str
中的内部char*
指针。这是深思熟虑的,因为更广泛的问题是你为什么要这样做即使您可以分配给str
的内部指针,这样做也会违反封装——例如,您假设内部指针是使用new
分配的。但是stl容器可以——而且确实——使用它们自己的内部分配机制,并且在未来应该可以自由地更改它们的实现,而不会破坏客户端代码。正如您可以在不破坏客户端代码的情况下更改类的实现一样。
是的,正如您在链接的文章中所看到的,如果x >= 0 && x < string.size()
,您可以修改string[x]
的值,但标准很清楚,您不能修改任何其他内容(当然也不能将&string[x]
作为可修改的空终止字符串的有效指针传递——记住string.c_str()
和string.data()
返回一个const char*
。
然而,您可以实现:
void swap(std::string& left, char* right) {
auto right_size = std::strlen(right);
auto left_size = left.size();
assert(left_size <= right_size);
std::string temp = std::move(left);
left = right;
std::copy(std::begin(temp), std::end(temp), right);
right[left_size] = ' ';
}
inline void swap(char* left, std::string& right) {
swap(right, left);
}
(住在这里)
你所做的在很多层面上都是错误的。
要用char *
指向的手动管理字符串"交换"std::string
,您需要手动管理该字符串,如:
std::string one = ...;
char *two = ...;
// swap:
std::string tmp = two;
delete[] two;
two = new char[one.size() + 1];
memcpy(two, one.c_str(), one.size() + 1);
one = tmp;