c++ - vector push_back a moved local var in c++11 测试和混淆

标签 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 << 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 
}

这是一个非常简单的来源,我的测试重点在std::move .如您所见,string x是本地变量,同时执行 v.push_back(x) , x被复制到 vector v , 所以 x还有"xxxxx"push_back 之后.在检查点 1 之后,x消失了(它只是本地的)但是 vector vx 以来具有其值(value)在做 v.push_back(x) 时被复制, 所以没关系!!

至于string y , 它被 move 到 vector v因为std::move被使用,所以你可以 见 cout << "y=" << y显示"y=" , 不是 "y=yyyyy" , 这是正确的行为。

我没有得到的是,在检查点 2 之后,字符串 y ,因为本地变量有它的生命终结, 所以 vector v作为y的所有者(因为 yv move 到 vector push_back(std::move(y)),应该包含无效元素,因为 y 作为堆栈局部变量,在检查点 2 处生命结束!

我很困惑,在检查点 2 之后, vector v还有"yyyyy" , y move 到 vector v , 如果 vector v只要有一个指针vptr = &y , 自 y是栈内存中的局部变量,在它的作用域结束后,栈就消失了,所以 vector vptr没用,看来这不是真的!

所以一定是vector有自己的内存来保存"yyyyy"在它自己的,但如果这是 情况,与push_back(x)相同,所以为什么要麻烦 std::move(y)

我错过了什么吗?

最佳答案

您可以将 std::string 想象成一个智能指针。 std::string 变量指向存储在其他地方的实际字符串数据。当您std::move 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 move 到 vector 中时。字符串数据现在是 vector 所拥有的字符串的一部分,y 不再与它有任何关系。当 y 超出范围时,它对 vector 中的数据没有影响,因为 y 不再有指向它的指针。

关于c++ - vector push_back a moved local var in c++11 测试和混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17460707/

相关文章:

android - C++参数匹配/推导

c++ - 我应该如何循环 C++11 中的枚举类?

c++ - 在 if-else block 中实现类似 SFINAE 的效果

c++ - 删除 vector 中的字符串

r - 更改条件以替换向量中的元素

c++ - 什么时候更喜欢 lambda 中的显式捕获而不是隐式捕获?

c++ - c++错误c2440使用带有2d参数的构造函数

c++11 - 从参数包中的基类继承构造函数

c++ - 我有不同的类,我想用这些类中的对象创建一个 vector 并按值对其进行排序

c++ - 如何使用 Cmake 为 SimuroSot 模拟器构建(从 DevCpp 转换)Win32 DLL