最近看到std::move()的神奇操作,能把std::string的字符串掏空?快吓懵我了,决定深究其原理,呵呵。
查看源码:
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept
{
return static_cast<typename std::remove_reference<_Tp>::type&&>(__t);
}
天下乌鸦一般黑,不就是个强转换嘛,吓得我快死了。
假设typename 是std::string类型:
std::string str;
那么std::move(str);
等同:static_cast<std::string&&>(str);
等同:(std::string&&)(str);
g++ test.cpp -o test -std=c++11
test.cpp
#include <stdio.h>
#include <string>
#include <utility>
#include <iostream>
class MyString : public std::string
{
public:
MyString() : std::string() {
printf("MyString:1\n");
}
MyString(const char* data) : std::string(data) {
printf("MyString:2\n");
}
MyString(MyString&& str) : std::string( std::move(str) ) {
printf("MyString:3\n");
}
MyString operator = (MyString&& str){
this->swap(str); // 试试把它注释掉你就知道了
printf("operator:1\n");
}
};
int main(int argc, char* argv[])
{
MyString str1 = "123";
std::cout << "str1=" << str1 << std::endl;
std::cout << "----------" << std::endl;
#if 1
// 下面三句同等效果,呵呵
MyString str2 = "456";
str2 = (MyString &&)(str1);
//MyString str2 = static_cast<MyString&&>(str1);
//MyString str2 = std::move(str1);
#else
// 下面三句同等效果,呵呵
MyString str2 = (MyString &&)(str1);
//MyString str2 = static_cast<MyString&&>(str1);
//MyString str2 = std::move(str1);
#endif
std::cout << "str1=" << str1 << std::endl;
std::cout << "str2=" << str2 << std::endl;
return 0;
}
输出结果:
MyString:2
str1=123
----------
MyString:2
operator:1
str1=456
str2=123
如果把重载函数里面的this->swap(str);注释掉会有另一种结果。
MyString operator = (MyString&& str){
// this->swap(str); // 试试把它注释掉你就知道了
printf("1111111\n");
}
输出结果:
MyString:2
str1=123
----------
MyString:2
operator:1
str1=123
str2=456