Int变量的值在移动后不会发生变化

时间:2015-08-03 16:58:44

标签: vector move-semantics

我已经阅读了移动语义的基础知识,并且我做了几个测试。 案例#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或者未定义的东西。

1 个答案:

答案 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();
}