c++ - std::string 的对象真的可以 move 吗?

标签 c++ string pointers move-semantics

我们知道,一个可 move 的对象,当它被分配给另一个相同类型的对象时,不会被深度复制。通过这种方式,我们可以节省很多时间。 但是今天,我发现了一个很奇怪的现象。请查看代码如下。

#include <string>
#include <iostream>
int main() {
std::string s1 = "s1";
std::string s2 = "s2";

std::cout << "  s1[" << ( void* ) &s1[0] << "]:" + s1
    << ", s2[" << ( void* ) &s2[0] << "]:" + s2
    << std::endl;
s1.swap( s2 );
std::cout << "  s1[" << ( void* ) &s1[0] << "]:" + s1
    << ", s2[" << ( void* ) &s2[0] << "]:" + s2
    << std::endl;

s2 = std::move(s1);
std::cout << "  s1[" << ( void* ) &s1[0] << "]:" + s1
    << ", s2[" << ( void* ) &s2[0] << "]:" + s2
    << std::endl;

return EXIT_SUCCESS; }

move 后,虽然字符串的内容变了,但是真正存放字符串数据的地址并没有变。

如果内存地址不会改变,我们是否有理由确认实际上将执行深度复制而不是仅仅分配一个指向目标成员的指针?

谢谢! 里昂

最佳答案

a movable object is one would not be copied deeply when it be assigned to another one of same type

只有在有意义的情况下。在下面的片段中

int i0 = 11;
int i1 = std::move(i0);

不会因为没有东西可以偷而“偷”。所以这个问题的前提是有缺陷的—— move 操作会“窃取”被 move 的内容,如果这样做是有意义的话。

另请注意,在 C++ 世界中,与 Java 和 C# 不同,对象是占用内存的一切 - 整数、指针、字符 - 所有这些都是对象。

std::string 使用称为“短字符串优化”或 SSO 的优化技术.如果字符串足够短(并且“足够短”是实现定义的),则不会动态分配缓冲区,因此不会“窃取”任何内容。当 move 如此短的字符串时,字符串的内容非常短,它只是被复制到 move 到的字符串中,而不会弄乱动态分配的缓冲区。

关于c++ - std::string 的对象真的可以 move 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52904157/

相关文章:

c++ - 在 paintEvent 中创建两个 QPainter

c++ - 如何在 C++ 中使用 ascii 值处理大于 9 的值

java - 删除字符串中最后一个已知单词

c - C套接字编程中不兼容的指针类型转换警告

c++ - 如何用指针交换两个变量

c - 使用它时是否可以在不使用 malloc 的情况下增加 char 数组?

c++ - 编译时模板 `std::integral_constant` 计数器 - 如何实现它?

c++ - 未命名命名空间中的全局非静态变量

java - 创建和使用带有代理对的字符串

C - 计数器不工作