C++ 向量推回c+中移动的局部变量+;11、测试和混淆

C++ 向量推回c+中移动的局部变量+;11、测试和混淆,c++,c++11,vector,move-semantics,C++,C++11,Vector,Move Semantics,以下测试是在g++4.8.1中编译的 int main() { vector<string> v ; v.push_back("33333") ; v.push_back("44444") ; v.push_back("55555") ; { string x("xxxxx") ; v.push_back(x) ; //copy cout << "x=" << x &l

以下测试是在g++4.8.1中编译的

int main()
{
    vector<string> v ;
    v.push_back("33333") ;
    v.push_back("44444") ;
    v.push_back("55555") ;

    {
        string x("xxxxx") ;
        v.push_back(x) ; //copy 
        cout << "x=" << x << endl ; //x=xxxxx
    } //checkpoint1

    {
        string y("yyyyy") ;
        v.push_back(std::move(y)) ; //move 
        cout << "y=" << y << endl ; //y=
    } //checkpoint2

    for(auto const i : v)
        cout << i << " " ; 
    cout << endl ; //33333 44444 55555 xxxxx yyyyy 
}
intmain()
{
向量v;
v、 向后推(“33333”);
v、 推回(“44444”);
v、 向后推(“55555”);
{
字符串x(“xxxxx”);
v、 向后推(x);//复制

cout您可以将
std::string
想象成一种智能指针。
std::string
变量指向存储在其他地方的实际字符串数据。当您
std::move
a
std::string
时,新字符串被赋予指向该数据的指针,旧字符串被清除

下面是一个非常简单的工作原理:

class MyString {
  public:
    // Move constructor
    MyString(MyString&& that)
      // Just make our string data point to the other string
      : string_data(that.string_data)
    {
      // And make sure the string we are moving from no longer points
      // to that data so it won't get freed when the other string
      // is destructed.         
      that.string_data = 0;
    }

    // Copy constructor
    MyString(const MyString& that)
      // We can't take the other string's data, so we need a copy
      : string_data(new char[strlen(that.string_data)+1])
    {
      strcpy(string_data,that.string_data);
    }

    // Assignment using copy and swap idiom.
    MyString& operator=(MyString that)
    {
      std::swap(string_data,that.string_data);
      return *this;
    }

    ~MyString()
    {
      // string_data may be null if it has been moved from, but
      // that's ok -- it is safe to delete a null pointer.
      delete [] string_data;
    }

  private:
    char *string_data;
};

当您将
y
移动到向量中时。字符串数据现在是向量所拥有的字符串的一部分,并且
y
不再与它有任何关系。当
y
超出范围时,它对向量中的数据没有影响,因为
y
不再有指向它的指针。

移动构造函数,就像复制构造函数涉及两个对象:(a)原始源对象;(b)新创建的目标对象

在您的例子中,局部变量是源对象,目标对象是通过
push_back
新创建的对象,该对象放置在向量存储中

移动构造函数和复制构造函数的区别在于,按照惯例,源对象可能会被修改,并且不希望再次使用(源对象是“过期”对象)。这允许类作者进行可能损坏源对象的优化,例如传输(“移动”)从源对象到目标对象的资源


std::string
的情况下,可能每个字符串都包含一个指向动态分配数组的成员指针。移动构造函数可以简单地将指针从源对象交换到目标对象。

谢谢你,沃恩·卡托,我可以再问一个问题吗?根据你上面的陈述,std::string类似于智能指针,vaRy是一个本地变量,它的包含“yyyy”在其他地方,在它自己的被移动到vector之后,所以y与内存“yyyy”无关。从那以后,vector应该处理那个“yyyy”内存就像普通的智能指针一样……我说的对吗?@barfatchen:是的,间接地。向量负责它包含的字符串的内存,然后字符串负责它们指向的内存。对于
std::string
,小字符串优化可以使移动小字符串的成本更高