std::string 的对象真的可以移动吗?
Is a object of std::string really movable?
正如我们所知,一个可移动对象是当它被分配给另一个相同类型的对象时不会被深度复制的对象。这样,我们可以节省大量时间。 但是今天,我发现了一个现象。请查看代码如下。
#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; }
移动后,虽然字符串的内容发生了变化,但真正存储字符串数据的地址并没有改变。
如果内存添加不会更改,我们是否有理由确认实际上将执行深度复制,而不仅仅是指向目标成员的指针?
谢谢! 里昂
可
移动对象是分配时不会被深度复制的对象 到另一个相同类型
只有当它有意义时。 在以下代码片段中
int i0 = 11;
int i1 = std::move(i0);
不会仅仅因为没有什么可偷的而"偷窃"。 所以这个问题的前提是有缺陷的——如果有意义的话,移动操作会"窃取"移动的内容。
另请注意,在C++世界中,与 Java 和 C# 不同,对象是占用内存的所有内容 - 整数、指针、字符 - 所有这些都是对象。
std::string
使用一种称为"短字符串优化"或 SSO 的优化技术。如果字符串足够短(并且定义了"足够短"的实现(,则不会动态分配缓冲区,因此不会"窃取"任何内容。当移动如此短的字符串时,字符串的内容非常短,只需复制到移入的字符串中,而不会弄乱动态分配的缓冲区。
相关文章:
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- MSVC将仅移动结构参数解释为指针
- 自定义先决条件对移动分配运算符有效吗
- 返回值优化:显式移动还是隐式
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 可以使用移动语义更改或改进此C++代码吗?
- 使lambda不可复制/不可移动
- c++在使用指针时移动语义
- 将QGraphicsItem的移动区域限制在多边形区域内
- std::string 的对象真的可以移动吗?
- std::vector::emplace() 真的在面对抛出移动构造函数/赋值运算符时提供了强大的异常保证吗?
- std::string移动构造函数真的会移动吗
- 如何确保对象真的会被移动
- 我真的必须取消移动构造函数/移动结构中的所有成员还是只是指针