我已经阅读了移动语义的基础知识,并且我做了几个测试。 案例#1:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string st = "hello";
vector<string> vec;
vec.push_back(st);
cout << st;
cin.get();
}
在这种情况下,程序不会打印任何内容,因为&#34;你好&#34;已移至vector [0]。
案例#2:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int num=5;
vector<int> vec;
vec.push_back(num);
cout << num;
cin.get();
}
为什么程序打印&#34; 5&#34;?我认为num将是0或者未定义的东西。
答案 0 :(得分:0)
案例#1应打印&#34;你好&#34;。如果没有,那么你的编译器有bug,你应该升级到更新的版本或抱怨谁写过它。
案例#2正确打印&#34; 5&#34;。
但是,如果您更改了案例2中的第10行:
vec.push_back(st);
为:
vec.push_back(std::move(st));
你会得到你所期望的,打印到#34;&#34;因为矢量&#34;偷走&#34; st。
中的值 int
是c ++中的fundamental type,并且试图“偷”&#34;来自一个int变量并没有真正起作用,因为它没有任何资源。
std::string是资源所有者。它拥有&#34;拥有&#34;一个char数组(这不总是正确的,但为了简单起见,我们会假装它是。)
因此,当我们将std::move(st)
传递给push_back时,我们正在调用push_back的T&&重载,这会导致&#34;窃取&#34;通过调用std :: string的move constructor来释放st的句柄并将其提供给vec中新创建的std :: string。
但是,如果我们这样调用push_back:vec.push_back(st);
这不会&#34;窃取&#34;任何事情。相反,它将调用push_back的const T&重载,它只通过调用std::string
的正常复制构造函数来执行简单复制,这样我们就可以将st设置为&#34; hello&#34;和vec [0]设置了自己的版本&#34; hello&#34;。
请尝试以下代码,看看这一切是如何解决的:
#include <iostream>
#include <vector>
using namespace std;
struct Foo
{
Foo() // default constructor
{
cout << "Foo()" << endl;
}
Foo(const Foo&) // copy constructor
{
cout << "Foo(const Foo&)" << endl;
}
Foo(Foo&&) // move constructor
{
cout << "Foo(Foo&&)" << endl;
}
Foo& operator=(const Foo&) // copy assignment operator
{
cout << "operator=(const Foo&)" << endl;
return *this;
}
Foo& operator=(Foo&&) // move assignment operator
{
cout << "operator=(Foo&&)" << endl;
return *this;
}
~Foo()
{
cout << "~Foo()" << endl;
}
};
int main()
{
Foo f; // print: Foo();
vector<Foo> vec;
vec.push_back(f); // print: Foo(const Foo&)
vec.push_back(std::move(f)); // print: Foo(Foo&&)
Foo f2; // print: Foo()
f2 = f; // print: operator=(const Foo&)
f2 = std::move(f); // print: operator=(Foo&&)
cin.get();
}