移动语义在矢量重定位中的工作原理

How move semantic works in vector relocation?

本文关键字:工作 定位 语义 移动      更新时间:2023-10-16

根据我的理解,当vector增加其容量时,它会分配一个新的内存,将所有内容复制(移动?)到新数组中,然后销毁旧数组:

vector<int> v;
v.emplace_back(1);
v.emplace_back(2); cout<<&v[0]<<endl; // outputs 0x4b16d0
v.emplace_back(3); cout<<&v[0]<<endl; // outputs 0x4b16f0
         +-----+  
0x4b16d0 | 1 2 |  
         +-----+  
         +---------+  
0x4b16f0 | 1 2 3   |  
         +---------+  

在上面的例子中,1和2 move如何从0x4b16d00x4b16f0 ?


更新为用户定义的类

struct foo {
    foo() {}
    foo(const foo &) { cout << "copyn"; }
    foo(foo &&) noexcept { cout << "moven"; }
};
int main() {
    vector<foo> v;
    cout<<"1st emplace_back() n"; v.emplace_back(); cout<<" addr of 1st element: "<<&v[0]<<endl;
    cout<<"2nd emplace_back() n"; v.emplace_back(); cout<<" addr of 1st element: "<<&v[0]<<endl;
}
$ g++ -std=c++11 -g a.cpp; ./a.exe
1st emplace_back()
 addr of 1st element: 0x6f16d1
2nd emplace_back()
move
 addr of 1st element: 0x6f16f1

我的问题是,即使调用move因子,它仍然将数据从一个地方复制到另一个地方,是这样吗?

如果是这样,这是否意味着当vector使用move语义增加其容量时,它根本没有提高性能?

您的矢量是vector<int>。移动int和复制它是一样的,所以这里没有"性能增益"。

如果你有vector<std::string>,那么你会注意到差异;大字符串将从旧的内存位置移动到新的内存位置。这比在新位置复制构造新字符串并销毁旧字符串要快。

(正如Chris Beck所指出的,对象只有在它们的move-构造函数不能抛出时才会被移动,但我相信std::string就是这种情况)。

我不确定你想在你的foo的例子中测试什么,因为你的foo实际上不包含任何数据。