std :: string的对象真的可以移动吗?

问题描述 投票:3回答:1

正如我们所知,当一个可移动的物体被分配给另一个相同类型的物体时,它将不会被深深地复制。通过这种方式,我们可以节省大量时间。但是今天,我发现了一种现象。请查看以下代码。

#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; }

移动后,虽然字符串的内容已经改变,但是真正存储字符串数据的地址没有改变。

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

谢谢!莱昂

c++ string pointers move-semantics
1个回答
5
投票

当一个可移动物体被分配给另一个相同类型的物体时,它将不会被深深地复制

只有它有意义。在以下代码段中

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

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

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

std::string使用称为“短字符串优化”或SSO的优化技术。如果字符串足够短(并且“足够短”是实现定义的),则没有动态分配缓冲区,因此没有“偷”。当移动这样的短字符串时,字符串的内容很短,它只是复制到移入的字符串而不会弄乱动态分配的缓冲区。

© www.soinside.com 2019 - 2024. All rights reserved.