3

次のテストは 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ローカル var であるのに対し、 executev.push_back(x)xvectorvにコピーされるため、afterxはまだあります。checkpoint1以降はなくなってしまいましたが(ローカルのみ)、ベクトルはそのままコピーされているので大丈夫です!!"xxxxx"push_backxvxv.push_back(x)

については、 が使用されているためstring yベクトルに移動されているため、 ではなくが表示されていることがわかります。これは正しい動作です。vstd::movecout << "y=" << y"y=""y=yyyyy"

私が得られないのは、checkpoint2 の後y、ローカル var の寿命が尽きたため、文字列の所有者vとしての vector です ( は vectorによってvector に移動されるため、無効な要素を含む必要があります。スタック ローカル var として、チェックポイント2で寿命!yyvpush_back(std::move(y))y

checkpoint2 の後、 vectorvがまだ持っている が"yyyyy"vectorにy移動された後、 vectorがポインタだけを持っているv場合、スコープがなくなった後、スタックメモリ内のローカル var であるため、スタックがなくなったため、 vectorは役に立たないので、このように見えることに混乱しています違います!vvptr = &yyvptr

したがって、ベクトルには独自のメモリがあり、独自に保持する必要がありますが、これが当てはまる"yyyyy"場合は と同じです。push_back(x)std::move(y)

私は何かが恋しいですか?

4

2 に答える 2

3

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ベクトルに移動するとき。文字列データは、ベクターが所有する文字列の一部になり、yそれとは何の関係もありません。y範囲外になると、ベクター内のデータへのポインターがなくなるため、ベクター内のデータには影響しませyん。

于 2013-07-04T01:53:27.273 に答える