Cpp 右辺値参照 新しいページはコチラ

提供: yonewiki
移動: 案内, 検索
(右辺値参照)
(右辺値参照)
308行: 308行:
  
 
</syntaxhighlight>
 
</syntaxhighlight>
非常に長いサンプルになってしまいましたが、こんな感じでClassのメンバ変数を入れ替えるようなプログラム(staticで定義したメンバ関数swap 静的メンバ関数はオブジェクトからでなくても呼べる関数です。別で詳細は説明の予定。thisポインタが使えないクラスの中にあるだけの関数CRightSample::swap(…)のように呼び出すものです。)を作ってみました。算術演算子 = をオーバロード(関数として定義)していまして、(CRightRefSampleのインスタンス) = の後ろに(CRightRefSampleのインスタンス)が設定された場合の関数と(CRightRefSampleのインスタンス)が右辺値参照として設定されている場合の関数の2つをオーバロードしています。同じ代入演算子でも引数が右辺値参照のときはムーブ、引数が参照のときはコピーのように使い分けることができます。右辺値参照の変数は使わなくなる予定の変数ですので、引数で受け取った変数をコピーするのではなくムーブしてしまうようにして利用します。特にswapのような入れ替えではポインタの交換だけを行うことで入れ替えられますので、AとBの入れ替え処理では入れ替え用の一時的な変数に対してAをムーブし、ムーブしおわったAにBの値をムーブ、そして一時的に作った変数からBへムーブという具合に3回のムーブによりポインタの入れ替えができて内容を交換できます。今回はひとつのメンバ変数のみの入れ替えサンプルですが、クラスの中の要素が文字列のような配列であったり、構造体、クラスといったようなもっと複雑なデータを保持している場合にムーブすることでデータの受け渡しをすることができます。コピーを作らなくてもいいような処理にはムーブは資源の節約にもなるし、無駄な処理が無いため処理速度も改善されます。ムーブのような作業は別に右辺値参照を使うことなくできますので、必ずしも右辺値参照が必要なわけではないですが、参照を引数にした場合の処理と分けることができるのが特徴です。今回はstd::moveのような関数であえて右辺値として扱うことでムーブを実現していますが、右辺値参照を引数にしている部分に引数にスタティックなクラスメンバ関数や関数を定義してクラスのインスタンスを戻り値とするような関数を作った場合に純粋な右辺値が登場しますが、そのような場合でも同じようにムーブされて問題ない処理になるはずです。右辺値参照を引数にとるムーブコンストラクタや代入演算子のオーバロードによるムーブを活用できることを知っておくことで、よりよいクラスの使い方が可能となります。
+
非常に長いサンプルになってしまいましたが、こんな感じでClassのメンバ変数を入れ替えるようなプログラム(staticで定義したメンバ関数swap 静的メンバ関数はオブジェクトからでなくても呼べる関数です。別で詳細は説明の予定。thisポインタが使えないクラスの中にあるだけの関数CRightSample::swap(…)のように呼び出すものです。)を作ってみました。算術演算子 = をオーバロード(関数として定義)していまして、(CRightRefSampleのインスタンス) = の後ろに(CRightRefSampleのインスタンス)が設定された場合の関数と(CRightRefSampleのインスタンス)が右辺値参照として設定されている場合の関数の2つをオーバロードしています。同じ代入演算子でも引数が右辺値参照のときはムーブ、引数が参照のときはコピーのように使い分けることができます。右辺値参照の変数は使わなくなる予定の変数ですので、引数で受け取った変数をコピーするのではなくムーブしてしまうようにして利用します。特にswapのような入れ替えではポインタの交換だけを行うことで入れ替えられますので、AとBの入れ替え処理では入れ替え用の一時的な変数に対してAをムーブし、ムーブしおわったAにBの値をムーブ、そして一時的に作った変数からBへムーブという具合に3回のムーブによりポインタの入れ替えができて内容を交換できます。今回はひとつのメンバ変数のみの入れ替えサンプルですが、クラスの中の要素が文字列のような配列であったり、構造体、クラスといったようなもっと複雑なデータを保持している場合にムーブすることでデータの受け渡しをすることができます。コピーを作らなくてもいいような処理にはムーブは資源の節約にもなるし、無駄な処理が無いため処理速度も改善されます。ムーブのような作業は別に右辺値参照を使うことなくできますので、必ずしも右辺値参照が必要なわけではないですが、参照を引数にした場合の処理と分けることができるのが特徴です。今回はstd::moveのような関数であえて右辺値として扱うことでムーブを実現していますが、右辺値参照を引数にしている部分に引数にスタティックなクラスメンバ関数や関数を定義してクラスのインスタンスを戻り値とするような関数を作った場合に純粋な右辺値が登場しますが、そのような場合でも同じようにムーブされて問題ない処理になるはずです。右辺値参照を引数にとるムーブコンストラクタや代入演算子のオーバロードによるムーブを活用できることを知っておくことで、よりよいクラスの使い方が可能となります。同じような関数が多くなりがちですが、このあたりはテンプレートの活用によりさらにコーディングの効率はあげられると思います。ここでは、あまりややこしくならないように最小限のクラス化と、最小限のテンプレートクラスの利用でメモを作成しています。
 +
 
 +
 
 +
このプログラムを理解するにはオブジェクト(インスタンス)、ポインタ、nullptr、文字列操作、参照、クラス(コンストラクタ デストラクタ 静的メンバ関数 演算子のオーバロード)を理解しておく必要があります。
  
  

2014年10月24日 (金) 00:00時点における版



個人用ツール
名前空間

変種
操作
案内
ツールボックス