细节1: 内存分配在栈的变量会被转移托管
....
{
string str = "i will be free if out of scope";
}
....
栈变量在出了作用域后系统会自动释放栈上内存,但是如果将它move给了其他人,会怎么样呢?
string other;
{
string str = "i'm transferred...";
cout<<"str addr:"<<&str<<endl;
other = move(str);
cout<<"other addr:"<<&other<<endl;
}
cout<<other<<endl;
正常来说str对应的内存出了作用域后就应该释放了。但是实际上还是存在的。move操作将管理权一并交出。运行结果如下:
从运行结果来看,这两个string对应的是两个不同的地址。两个地址是独立的,move操作实际上是系统将这一块地址属于哪一个地址的登记改一下,实际上这一块内存根本没有发生任何变化。
打个比方,就好比说一个房产,原来登记在张三名下,“张三”就是地址。张三也有管理权。move就相当于过户。过户给李四后,“李四”就是这个房子的“地址”,管理权自然也交接给了李四。
那如果是堆上分配的内存呢?
string other;
{
string* str = new string("i'm transferred...");
other = move(*str);
delete str; // it's ok
}
cout<<other<<endl;
其实一样的。这里的delete是没有实际作用的。
细节2:指针可以move
继上面的例子,被转移的对象都是实例对象,如果是指针可不可以呢?
string *other;
{
string str("i'm transferred...");
*other = move(str); // not ok
}
cout<<*other<<endl;
有些时候需要move的对象比较复杂,处理化可能比较麻烦。想找个方便的方法,用一个指针去move。但是这样是不可以的。被move的对象必须实例化,不可以拿一个指针去接受move。
那指针就不能用于move吗?
标题我都写的,是可以的,但是不可以按上面的例子写。需要这样改一下
string *other;
{
string* str = new string("i'm transferred...");
cout<<"str:"<<str<<endl;
other = move(str);
cout<<"other:"<<other<<endl;
//delete str; // not ok
}
cout<<*other<<endl;
可以将指针move给另一个指针,所以这样用是可以的。
也可以发现,使用move的结果是使两个指针一致。
所以跟直接用=号的行为一样。那么为啥不干脆直接用=呢?












网友评论