std:move基本用法和理解
生活随笔
收集整理的這篇文章主要介紹了
std:move基本用法和理解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
場景:
參考:
1. Move Constructors and Move Assignment Operators (C++)
2. std::move
說明:
std::move 的函數原型.
/*** @brief Convert a value to an rvalue.* @param __t A thing of arbitrary type.* @return The parameter cast to an rvalue-reference to allow moving it. */ template<typename _Tp>constexpr typename std::remove_reference<_Tp>::type&&move(_Tp&& __t) noexcept{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }結構體 remove_reference 的原型,就是重載了多個結構體模板來獲取原類型 type.
/// remove_reference 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; };例子
以下用兩個例子來說明std::move的用法.
例子1
– 原lvalue值被moved from之后值被轉移,所以為空字符串.
– 摘錄自cppreference
輸出:
After copy, str is "Hello" After move, str is "" The contents of the vector are "Hello", "Hello"例子2
– 自定義自己的類對象支持moved from 操作,需要實現 Move Constructors and Move Assignment Operators
#include <iostream> #include <stdio.h>#include <utility> #include <vector> #include <string>class MemoryBlock { public:// Simple constructor that initializes the resource.explicit MemoryBlock(size_t length): _length(length), _data(new int[length]){std::cout << "In MemoryBlock(size_t). length = "<< _length << "." << std::endl;}// Destructor.~MemoryBlock(){std::cout << "In ~MemoryBlock(). length = "<< _length << ".";if (_data != nullptr){std::cout << " Deleting resource.";// Delete the resource.delete[] _data;}std::cout << std::endl;}// Copy constructor.MemoryBlock(const MemoryBlock& other): _length(other._length), _data(new int[other._length]){std::cout << "In MemoryBlock(const MemoryBlock&). length = "<< other._length << ". Copying resource." << std::endl;std::copy(other._data, other._data + _length, _data);}// Copy assignment operator.MemoryBlock& operator=(const MemoryBlock& other){std::cout << "In operator=(const MemoryBlock&). length = "<< other._length << ". Copying resource." << std::endl;if (this != &other){// Free the existing resource.delete[] _data;_length = other._length;_data = new int[_length];std::copy(other._data, other._data + _length, _data);}return *this;}// Retrieves the length of the data resource.size_t Length() const{return _length;}// Move constructor.MemoryBlock(MemoryBlock&& other): _data(nullptr), _length(0){std::cout << "In MemoryBlock(MemoryBlock&&). length = "<< other._length << ". Moving resource." << std::endl;// Copy the data pointer and its length from the// source object._data = other._data;_length = other._length;// Release the data pointer from the source object so that// the destructor does not free the memory multiple times.other._data = nullptr;other._length = 0;}// Move assignment operator.MemoryBlock& operator=(MemoryBlock&& other){std::cout << "In operator=(MemoryBlock&&). length = "<< other._length << "." << std::endl;if (this != &other){// Free the existing resource.delete[] _data;// Copy the data pointer and its length from the// source object._data = other._data;_length = other._length;// Release the data pointer from the source object so that// the destructor does not free the memory multiple times.other._data = nullptr;other._length = 0;}return *this;}private:size_t _length; // The length of the resource.int* _data; // The resource. };void TestSTLObject() {std::string str = "Hello";std::vector<std::string> v;// uses the push_back(const T&) overload, which means// we'll incur the cost of copying strv.push_back(str);std::cout << "After copy, str is \"" << str << "\"\n";// uses the rvalue reference push_back(T&&) overload,// which means no strings will be copied; instead, the contents// of str will be moved into the vector. This is less// expensive, but also means str might now be empty.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";}void TestMyObjectWithoutUseMove() {std::vector<MemoryBlock> v;MemoryBlock mb1(25);// MemoryBlock mb2(75);// MemoryBlock mb3(50);v.push_back(mb1);//v.push_back(mb2);//v.insert(v.begin() + 1, mb3); }void TestMyObjectWithUseMove() {std::vector<MemoryBlock> v;MemoryBlock mb1(25);// MemoryBlock mb2(75);// MemoryBlock mb3(50);v.push_back(std::move(mb1));//v.push_back(MemoryBlock(75));//v.insert(v.begin() + 1, MemoryBlock(50)); }int main(int argc, char const *argv[]) {//TestSTLObject();TestMyObjectWithoutUseMove();std::cout << "......................................." << std::endl;TestMyObjectWithUseMove();return 0; }輸出:
1. 注意,第一個函數每個對象多調用了拷貝構造函數,多創建了一次,而使用了move操作的只是移動了資源
2. 注意,vector即使 push_back 第二個對象時,會移動第一個對象,很奇怪,如果你把注釋去掉的話,會發現資源 Moving 很多次,這是 vector 實現影響了,比較清楚的看出來 Move 的特性的就是 push_back 一個參數.
3. 注意,g++ 4.8.1 的 vector push_back 多個對象時優化的沒 vs 好,vs 是調用 Move 構造器,而 g++ 是調用 Copy 構造器,你會發現拷貝構造函數會調用很多次.
總結
以上是生活随笔為你收集整理的std:move基本用法和理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XML具有哪些特点?相对于HTML的优势
- 下一篇: 程序媛计划——python正则表达式