以下测试在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 v
自 x
以来具有其值(value)在做 v.push_back(x)
时被复制, 所以没关系!!
至于string y
, 它被 move 到 vector v
因为std::move
被使用,所以你可以
见 cout << "y=" << y
显示"y="
, 不是 "y=yyyyy"
, 这是正确的行为。
我没有得到的是,在检查点 2 之后,字符串 y
,因为本地变量有它的生命终结,
所以 vector v
作为y
的所有者(因为 y
被 v
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/