C++11新しいプロパティアプリケーション:プログラムをより効率的に(右の参照で深いコピーを避ける)

4268 ワード

ここの内容は参考書「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コンパイラでコードを書いて検証しようとすると、娘をののしるかもしれない.出力結果は同じではないか.
私はほほほするしかありません.コンパイラがプログラムを最適化したので、あなたは見えません.どうしても理解しなければならないなら、一歩一歩反アセンブリを見てみましょう.満足しています.
次に、右の値を使用して深いコピーを回避する方法について説明します.
この時、あなたはまたつぶやくかもしれませんか?深いコピーをするのはいいことではないでしょうか.私たちが書いた賦値構造関数に深いコピーを実現させるのは、2つのポインタが同じものを指したり、同じものを2回削除したりすることを避けるためです.
しかし、すべては絶えず発展している.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;  
} 

右値参照と移動の意味があり、クラスを設計および実装する際に、大量のリソースを動的に申請する必要があるクラスに対しては、アプリケーションの効率を向上させるために、右値参照のコピー構造関数と付与関数を設計する必要があります.なお、一般的には、右の値で参照されるコンストラクタを提供するとともに、左の値で参照される定数のコピーコンストラクタを提供し、移動が不可能であることを保証し、コピーコンストラクタを使用することもできます.