1.用法
std::move用来指示对象t可以“被移动”, 即允许从t到另一种对象的高效率的转换
效果就是static_cast强转的作用。通过把左值的数据转换成右值,如果push_back,之后就可以直接传递指针。
2.官方例子
#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
{
std::string str = "Hello";
std::vector<std::string> v;
// 使用 push_back(const T&) 重载,
// 表示我们将带来复制 str 的成本
v.push_back(str);
std::cout << "After copy, str is \"" << str << "\"\n";
// 使用右值引用 push_back(T&&) 重载,
// 表示不复制字符串;而是
// str 的内容被移动进 vector
// 这个开销比较低,但也意味着 str 现在可能为空。
v.push_back(std::move(str));
std::cout << "After move, str is \"" << str << "\"\n";
std::cout << "The contents of the vector are \"" << v[0]
<< "\", \"" << v[1] << "\"\n";
}
3. 我的例子
#include<iostream>
#include<string>
#include<vector>
#include<utility>
//定义自己的move
namespace csstd{
/*define remove_reference overload*/
template<typename _Tp>
struct remove_reference
{typedef _Tp type;};
template<typename _Tp>
struct remove_reference<_Tp&>
{typedef _Tp type;};
template<typename _Tp>
struct remove_reference<_Tp&&>
{typedef _Tp type;};
template<typename _Tp>
constexpr typename csstd::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename csstd::remove_reference<_Tp>::type&&>(__t);}
}
void TESTSTLMOVE() {
std::string str = "hello";
std::vector<std::string> vec;
//push the value into the vector arrary;
vec.push_back(str);
std::cout << "After copy the value is " << str << std::endl;
//After using the move function to push back the str value;
vec.push_back(std::move(str));
std::cout << "After using move function, copy the value is \"" << str << "\"\n";
std::cout << "the first value of vector is " << vec[0] << "the second value is " <<
vec[1] << std::endl;
}
class MemoryBlock {
public:
//default constructor
MemoryBlock(size_t size)
: _size(size)
, _data(new int[size])
{
std::cout << "default constructor size is " << _size
<< std::endl;
}
//destructor
~MemoryBlock(){
std::cout << "In memory destrcutor, length is " << _size << std::endl;
if (_data != nullptr) {
std::cout << "delete the _data" <<std::endl;
delete [] _data;
}
}
//copy construct
MemoryBlock(const MemoryBlock& block)
: _size(block._size)
, _data(new int[_size])
{
std::cout << "In copy construct, length is " << _size << std::endl;
std::copy(block._data, block._data + _size, _data);
}
//operator overload
MemoryBlock& operator=(const MemoryBlock& other)
{
if (this != &other) {
delete[] _data;
_size = other.getSize();
_data = new int[_size];
std::copy(other._data, other._data + _size, _data);
}
return *this;
}
size_t getSize() const{
return _size;
}
//move construct
MemoryBlock(MemoryBlock&& block)
: _data(block._data)
, _size(block._size)
{
std::cout << "In move construct, length is " << _size << std::endl;
block._size = 0;
block._data = nullptr;
}
MemoryBlock& operator=(MemoryBlock&& block)
{
std::cout << "In move copy construct, length is " << block._size << std::endl;
if (&block != this) {
delete[] _data;
_data = block._data;
_size = block._size;
block._data = nullptr;
block._size = 0;
}
return *this;
}
//move assignment operator
private:
size_t _size;
int* _data;
};
void TESTObjwithoutMOVE() {
std::vector<MemoryBlock> v;
MemoryBlock m1(25);
MemoryBlock m2(24);
MemoryBlock m3(24);
v.push_back(m1);
v.push_back(m2);
v.push_back(m3);
v.push_back(m3);
//v.push_back(mm);
//v.push_back(csstd::move(mm));
//v.push_back(mm);
// std::cout << "the mm is " << mm.getSize() << std::endl;
std::cout << v.size() << std::endl;
}
void TESTObjwithMove()
{
std::vector<MemoryBlock> v;
MemoryBlock m1(25);
MemoryBlock m2(24);
MemoryBlock m3(24);
v.push_back(csstd::move(m1));
v.push_back(m2);
v.push_back(m3);
v.push_back(csstd::move(m2));
//v.push_back(mm);
//v.push_back(csstd::move(mm));
}
int main() {
//TESTSTLMOVE();
TESTObjwithoutMOVE();
std::cout << "-----------------------" << std::endl;
TESTObjwithMove();
return 0;
}
通过例子可以看到在std::move传入值时,只是传入指针的值,并没有做拷贝构造函数,但是当vector超过capacity的时候,进行再次的copy构造函数时,会对原有的值有影响。例子中我们模拟了std::move的执行
4.参考
&&参数:https://docs.microsoft.com/en-us/cpp/cpp/rvalue-reference-declarator-amp-amp?view=vs-2019
左值与右值:https://docs.microsoft.com/en-us/cpp/cpp/lvalues-and-rvalues-visual-cpp?view=vs-2019
constexpr:https://en.cppreference.com/w/cpp/language/constexpr
左值右值:https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/index.html
https://docs.microsoft.com/en-us/cpp/cpp/lvalues-and-rvalues-visual-cpp?view=vs-2019
https://blog.youkuaiyun.com/swartz_lubel/article/details/59620868