您好,登錄后才能下訂單哦!
今天小編給大家分享一下C++中右值引用與移動語義的方法是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
充分利用臨時對象,避免拷貝。
在 C++11之后,C++根據
被標識:可通過不同標識符指代同一實體。(對象/內存)
可移動:可作為移動語義函數的參數,例如移動構造,移動賦值。
將值分為以下類別:
泛左值:被標識
左值:被標識且不可移動
將亡值:被標識可移動
右值:可移動
將亡值:被標識可移動
純右值:不被標識且可移動
int a = 1;
a是一個左值,左值是關聯了名稱的內存位置。
int a = 1;
1是一個純右值,純右值是指不被標識且可移動的值,例如字面量。
using std::string; string get() { string ret = "abc"; return ret; } string str = get();
get() 函數調用會產生一個臨時變量賦給str,這個臨時變量是將亡值,此時的賦值是移動語義(c++11之前是復制語義)。
int a = 1; int& a_lref = a;
a_lref是左值引用
int&& rref = 1;
rref是右值引用(rref是類型為右值引用的左值)
void foo(int&& rref) { } int a = 1; foo(std::move(a));
std::move本質是類型轉換,即把左值轉換成右值
注意:被轉換的對象不應再被使用,否則結果難以預計(通常內存會被轉移)
class Foo { public: Foo() { m_data = malloc(32); } Foo(const Foo& rhs) { if(m_data == nullptr) { m_data = malloc(32); } memcopy(m_data,rhs.m_data,32); } Foo& operator = (const Foo& rhs) { if(m_data == nullptr) { m_data = malloc(32); } memcopy(m_data,rhs.m_data,32); return *this; } Foo(Foo&& rhs) noexcept { m_data = rhs.m_data; rhs.m_data = nullptr; } Foo& operator = (Foo&& rhs) noexcept { m_data = rhs.m_data; rhs.m_data = nullptr; return *this; } private: void* m_data }
移動構造的本質就是內存資源所有權的轉移
#include <iostream> #include <cstdlib> #define LOG(Args) std::cout << "==== " << Args << " ====" << std::endl namespace My { class Vector { public: Vector() noexcept { LOG("Ctor"); m_data = new int[] {0, 0, 0, }; } ~Vector() { LOG("Dector"); m_data = new int[] {0, 0, 0, }; } Vector(const Vector& rhs) { LOG("Copy"); if (m_data == nullptr) { m_data = new int[3]; } memcpy(m_data, rhs.m_data, 3 * sizeof(int)); } Vector& operator = (const Vector& rhs) { LOG("Copy Operator = "); if (m_data == nullptr) { m_data = new int[3]; } memcpy(m_data, rhs.m_data, 3 * sizeof(int)); return *this; }; Vector& operator = (Vector&& rhs) noexcept { LOG("Move Operator = "); m_data = rhs.m_data; rhs.m_data = nullptr; return *this; }; Vector(Vector&& rhs) noexcept { LOG("Move"); m_data = rhs.m_data; rhs.m_data = nullptr; } void print() { std::cout << "X = " << m_data[0] << " , " << "Y = " << m_data[1] << " , " << "Z = " << m_data[2] << std::endl; } void set(int x,int y,int z) { m_data[0] = x; m_data[1] = y; m_data[2] = z; } private: int* m_data; }; } My::Vector Get() { My::Vector vec; vec.set(4, 5, 6); return vec; } void main() { My::Vector vec1; My::Vector vec2; LOG("vec1"); vec1.print(); vec1.set(0, 1, 2); LOG("vec1"); vec1.print(); vec1 = vec2; LOG("vec1"); vec1.print(); vec1 = std::move(vec2); LOG("vec1"); vec1.print(); My::Vector* vp1 = new My::Vector(); LOG("vp1"); vp1->print(); My::Vector* vp2 = new My::Vector(*vp1); LOG("vp2"); vp2->print(); My::Vector* vp3 = new My::Vector(std::move(*vp1)); LOG("vp3"); vp3->print(); My::Vector* vp4 = new My::Vector(Get()); LOG("vp4"); vp4->print(); }
輸出
以上就是“C++中右值引用與移動語義的方法是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。