欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你了解C++中的右值引用與移動語義

 更新時間:2023年03月31日 10:48:39   作者:寡人正在Coding  
本篇文章主要為大家詳細介紹了C++中的右值引用與移動語義的相關(guān)知識,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

意義

充分利用臨時對象,避免拷貝。

左值右值

值類別

在 C++11之后,C++根據(jù)

  • 被標識:可通過不同標識符指代同一實體。(對象/內(nèi)存)
  • 可移動:可作為移動語義函數(shù)的參數(shù),例如移動構(gòu)造,移動賦值。

將值分為以下類別:

泛左值:被標識

  • 左值:被標識且不可移動
  • 將亡值:被標識可移動

右值:可移動

  • 將亡值:被標識可移動
  • 純右值:不被標識且可移動

左值

int a = 1;

a是一個左值,左值是關(guān)聯(lián)了名稱的內(nèi)存位置。

純右值

int a = 1;

1是一個純右值,純右值是指不被標識且可移動的值,例如字面量。

將亡值

using std::string;
string get()
{
	string ret = "abc";
	return ret;
}

string str = get();

get() 函數(shù)調(diào)用會產(chǎn)生一個臨時變量賦給str,這個臨時變量是將亡值,此時的賦值是移動語義(c++11之前是復(fù)制語義)。

左值引用

int a = 1;
int& a_lref = a;

a_lref是左值引用

右值引用

int&& rref = 1;

rref是右值引用(rref是類型為右值引用的左值)

std::move()

void foo(int&& rref)
{
}

int a = 1;
foo(std::move(a));

std::move本質(zhì)是類型轉(zhuǎn)換,即把左值轉(zhuǎn)換成右值

注意:被轉(zhuǎn)換的對象不應(yīng)再被使用,否則結(jié)果難以預(yù)計(通常內(nèi)存會被轉(zhuǎn)移)

移動構(gòu)造&移動賦值運算符重載

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
}

移動構(gòu)造的本質(zhì)就是內(nèi)存資源所有權(quán)的轉(zhuǎn)移

測試&驗證

#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();
}

輸出

到此這篇關(guān)于一文帶你了解C++中的右值引用與移動語義 的文章就介紹到這了,更多相關(guān)C++右值引用 移動語義 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt編寫地圖綜合應(yīng)用之繪制雨量分布

    Qt編寫地圖綜合應(yīng)用之繪制雨量分布

    雨量分布圖是在區(qū)域地圖基礎(chǔ)上,針對區(qū)域中的每個最小單位區(qū)域比如縣城點位不同顏色顯示。本文將詳細為大家介紹如何通過QT編寫繪制雨量分布,感興趣的小伙伴可以了解一下
    2021-12-12
  • Qt中QtWebEngine加載本地網(wǎng)頁跨域問題的總結(jié)

    Qt中QtWebEngine加載本地網(wǎng)頁跨域問題的總結(jié)

    本文主要介紹了Qt中QtWebEngine加載本地網(wǎng)頁跨域問題的總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2022-04-04
  • C++運算符重載限制介紹

    C++運算符重載限制介紹

    這篇文章主要介紹了C++運算符重載限制,關(guān)于運算符的重載并不是隨心所欲的。C++給出了一些限制,從而保證了規(guī)范,以及程序運行的準確性,下面來了解C++運算符重載限制的詳細內(nèi)容吧,需要的朋友也可以參考一下
    2022-01-01
  • 基于getline()函數(shù)的深入理解

    基于getline()函數(shù)的深入理解

    本篇文章是對getline()函數(shù)的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 使用C++的ORM框架QxORM詳解

    使用C++的ORM框架QxORM詳解

    這篇文章主要介紹了使用C++的ORM框架QxORM的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 基于C++寫一個推箱子小游戲

    基于C++寫一個推箱子小游戲

    這篇文章主要為大家詳細介紹了基于C++寫一個推箱子小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2023-09-09
  • C++自動析構(gòu)時的順序問題

    C++自動析構(gòu)時的順序問題

    這篇文章主要介紹了C++自動析構(gòu)時的順序,通過實例代碼給大家講解了C++ 構(gòu)造與析構(gòu)的執(zhí)行順序,代碼簡單易懂,非常不錯對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • C++深入刨析muduo中的抽象類Poller

    C++深入刨析muduo中的抽象類Poller

    muduo網(wǎng)絡(luò)庫中Poller類是一個抽象類,用戶使用PollPoller或者EPollPoller類,下面跟隨小編一起來詳細了解一下
    2022-04-04
  • C++實現(xiàn)中綴表達式轉(zhuǎn)后綴表達式

    C++實現(xiàn)中綴表達式轉(zhuǎn)后綴表達式

    這篇文章主要為大家詳細介紹了C++實現(xiàn)中綴表達式轉(zhuǎn)后綴表達式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • Qt利用QDrag實現(xiàn)拖拽拼圖功能詳解

    Qt利用QDrag實現(xiàn)拖拽拼圖功能詳解

    QDrag類為MIME-based拖拽數(shù)據(jù)轉(zhuǎn)換提供支持。本文為大家主要介紹如何利用QDrag類實現(xiàn)拖拽拼圖功能。左邊是打散的圖,拖動到右邊進行復(fù)現(xiàn),此外程序還支持手動拖入原圖片,感興趣的可以了解一下
    2022-07-07

最新評論