天天看點

C++ move()排序函數用法詳解(深入了解,一文學會)1 左值和右值2 引用3. 左值引用和右值引用4 move_backward()函數

        move() 算法會将它的前兩個輸入疊代器參數指定的序列移到第三個參數定義的目的序列的開始位置,第三個參數必須是輸出疊代器。這個算法傳回的疊代器指向最後一個被移動到目的序列的元素的下一個位置。

        這是一個移動操作,是以無法保證在進行這個操作之後,輸入序列仍然保持不變;源元素仍然會存在,但它們的值可能不再相同了,是以在移動之後,就不應該再使用它們。如果源序列可以被替換或破壞,就可以選擇使用 move() 算法。如果不想擾亂源序列,可以使用 copy() 算法。

C++ move()排序函數用法詳解(深入了解,一文學會)1 左值和右值2 引用3. 左值引用和右值引用4 move_backward()函數

本文作者原創,轉載請附上文章出處與本文連結。

C++ move()排序函數用法詳解(深入了解,一文學會)目錄

1 左值和右值

2 引用

3. 左值引用和右值引用

    3.1 左值引用

    3.2 右值引用

1 左值和右值

        要了解move函數首先弄清左值引用和右值引用。左值、左值引用、右值、右值引用

         左值: 是可以放在指派号左邊可以被指派的值;左值必須要在記憶體中有實體;

         右值:當在指派号右邊取出值賦給其他變量的值;右值可以在記憶體也可以在CPU寄存器。

         注:一個對象被用作右值時,使用的是它的内容(值),被當作左值時,使用的是它的位址。

2 引用

        引用是C++文法做的優化,引用的本質還是靠指針來實作的。引用相當于變量的别名。

        引用可以改變指針的指向,還可以改變指針所指向的值。

        引用的基本規則:

注:聲明引用的時候必須初始化,且一旦綁定,不可把引用綁定到其他對象;即引用必須初始化,不能對引用重定義;

對引用的一切操作,就相當于對原對象的操作。

3. 左值引用和右值引用

    3.1 左值引用

         左值引用的基本文法:type &引用名 = 左值表達式;

    3.2 右值引用

        右值引用的基本文法type &&引用名 = 右值表達式;

        右值引用在企業開發人員在代碼優化方面會經常用到。

        右值引用的“&&”中間不可以有空格。

std::move并不能移動任何東西,它唯一的功能是将一個左值強制轉化為右值引用,繼而可以通過右值引用使用該值,以用于移動語義。從實作上講,std::move基本等同于一個類型轉換:static_cast<T&&>(lvalue);

C++ 标準庫使用比如vector::push_back 等這類函數時,會對參數的對象進行複制,連資料也會複制.這就會造成對象記憶體的額外建立, 本來原意是想把參數push_back進去就行了,通過std::move,可以避免不必要的拷貝操作。

std::move是為性能而生。

std::move是将對象的狀态或者所有權從一個對象轉移到另一個對象,隻是轉移,沒有記憶體的搬遷或者記憶體拷貝。

用法:

#include <iostream>                                      // For standard streams
#include <iterator>                                      // For stream iterators and begin() and end()
#include <algorithm>                                     // For reverse_copy() and copy_if()
#include <cctype>                                        // For toupper() and isalpha()
#include <string>
#include <vector>
#include <deque>

using namespace std;
using std::string;

int main()
{
	std::vector<std::string> v;
	std::string str = "Knock";

	std::cout << "Copying str\n";
	v.push_back(str); // 使用左值引用版本,将str複制到數組array中

	std::cout << "str: " << str << '\n';
	std::cout << "vector: " << v[0] << '\n';

	std::cout << "\nMoving str\n";

	v.push_back(std::move(str)); // 使用右值引用版本,将str移動到數組array中

	std::cout << "str: " << str << '\n';
	std::cout << "vector:" << v[0] << ' ' << v[1] << '\n';

}

           
C++ move()排序函數用法詳解(深入了解,一文學會)1 左值和右值2 引用3. 左值引用和右值引用4 move_backward()函數

上述例子可以清晰地看出來,複制的時候str中的值沒有改變,而在移動的例子中str中的值就已經消失,也就是說真正的把值移動了出去。 

4 move_backward()函數

從末尾開始将[first,last]範圍内的元素移到終止于結果的範圍内。

該函數首先将*(last-1)移至*(result-1),然後向後跟随這些元素之前的元素,直到到達第一個元素(并包括它)。

#include <iostream>     // std::cout
#include <algorithm>    // std::move_backward
#include <vector>   
using namespace std;
int main()
{
	std::vector <int> vec1{ 1, 2, 3, 4, 5 };
	std::vector <int> vec2{ 7, 7, 7, 7, 7 };

	// Print elements 
	std::cout << "Vector1 contains:";
	for (int i = 0; i < vec1.size(); i++)
		std::cout << " " << vec1[i];
	std::cout << "\n";

	// Print elements 
	std::cout << "Vector2 contains:";
	for (unsigned int i = 0; i < vec2.size(); i++)
		std::cout << " " << vec2[i];
	std::cout << "\n\n";


	// std::move_backward function 
	std::move_backward(vec2.begin(), vec2.begin() + 4, vec1.begin() + 4);

	// Print elements 
	std::cout << "Vector1 contains after std::move_backward function:";
	for (unsigned int i = 0; i < vec1.size(); i++)
		std::cout << " " << vec1[i];
	std::cout << "\n";

	return 0;

}
           
C++ move()排序函數用法詳解(深入了解,一文學會)1 左值和右值2 引用3. 左值引用和右值引用4 move_backward()函數

繼續閱讀