程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++11新特性應用--讓你的程序更高效(右值引用避免深拷貝)

C++11新特性應用--讓你的程序更高效(右值引用避免深拷貝)

編輯:C++入門知識

C++11新特性應用--讓你的程序更高效(右值引用避免深拷貝)


這裡的內容注意參考書籍《深入應用C++11代碼優化與工程級應用》

今天,重溫一下右值。

使用右值,使得我們的C++程序更加高效。

我們可以簡單把右值理解為一個臨時變量。之前,我們誰也不會在意這個臨時變量,但要付出了效率的代價。

而右值引用就是對右值進行的引用類型,與我們通常所說的引用一樣,一定要記得初始化。

左右值區分:

void func(X& x); // 左值引用 重載
void func(X&& x); // 右值引用 重載

X x;
X foobar();

func(x); // 參數為左值,調用func(X& x);
func(foobar()); // 參數為右值,調用func(X&& x);

再看看這個:

// lvalues:
  //
  int i = 42;
  i = 43; // ok, i is an lvalue
  int* p = &i; // ok, i is an lvalue
  int& foo();
  foo() = 42; // ok, foo() is an lvalue
  int* p1 = &foo(); // ok, foo() is an lvalue

  // rvalues:
  //
  int foobar();
  int j = 0;
  j = foobar(); // ok, foobar() is an rvalue
  int* p2 = &foobar(); // error, cannot take the address of an rvalue
  j = 42; // ok, 42 is an rvalue

之前在初始化列表的博客中提到過,使用初始化列表進行初始化,比在構造函數中初始化效率更高,道理是一樣的。

這結論一定是正確的,當你用VS編譯器試圖寫代碼進行驗證的時候,你也許就會罵娘了,這他媽輸出結果不是一樣的嗎。

我只能呵呵了,因為編譯器對程序進行了優化,你是看不到的。如果非要搞明白,就試圖一步一步看看反匯編吧,包你滿意。

下面就說說使用右值如何避免深拷貝。

此時,你可能又要犯嘀咕了?
深拷貝不是好事兒嗎,使我們自己寫的賦值構造函數實現深拷貝嗎,是為了避免兩個指針指向同一個東西,也避免刪除同一個東西兩次。

但,凡是都是在不停的發展的。因為C++11引入了右值概念,所以這就使得之前我們所寫的賦值構造函數並不是那麼完美了。主要還是效率的問題了。

下面就是用到了移動構造函數~之前也有提到過啊:

MyString(MyString&& str) {  
         std::cout <<"Move Constructor is called! source: "<< str._data << std::endl;  
         _len = str._len;  
         _data = str._data;         // 避免了不必要的拷貝  
         str._len = 0;  
         str._data = NULL;  
}  

MyString&operator=(MyString&& str) {  
         std::cout <<"Move Assignment is called! source: "<< str._data << std::endl;  
         if (this != &str) {  
                      _len = str._len;  
                      _data = str._data;    // 避免了不必要的拷貝  
                      str._len = 0;  
                      str._data = NULL;  
         }  
         return *this;  
} 

有了右值引用和移動語義,在設計和實現類時,對於需要動態申請大量資源的類,應該設計右值引用的拷貝構造函數和賦值函數,以提高應用程序的效率。需要注意的是,我們一般在提供右值引用的構造函數的同時,也會提供常量左值引用的拷貝構造函數,以保證移動不成還可以使用拷貝構造。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved