C++ 右辺値参照とmove

投稿者: | 2015/12/6 日曜日

右辺値参照は「あとは死ぬだけになったオブジェクトの参照」

右辺値参照がわかりづらいのでメモ&テスト

まず、生のデータNamaを定義しよう。

次にこれを扱うクラスNamaHandlerを定義しよう。

問題ない。コンストラクタでNAMAを初期化し、デストラクタで解放。なお例外はスルー。
しかしこのクラスには問題がある。コピーコンストラクタを定義してないので、コピーするとポインタがコピーされ、デストラクタで2重deleteになってしまう。よってコピーコンストラクタを定義しよう。

アサインメントのオペレーターも定義しよう。

コピーコンストラクタはインスタンスを作成するときに呼ばれる(=を使っても)。operator=は=したとき呼ばれる。
実行しよう

ここでNamaHanderを返す関数getNama()を定義しよう。

全部まとめたソース

このコードには論理的に問題はないが、やたらとコピーが呼ばれる。上の42行目と44行目でやたらと呼ばれる、しかも作ったオブジェクトをすぐ捨てていてもったいない。そこで右辺値参照を定義してみる。

&を&&に置き換えただけだが、実行してみるとここに来ることがわかる。どういう条件でくるのか?
参照があとは死ぬだけであとはデストラクタが動くだけのオブジェクトの参照のときに呼ばれる。
これを生かして実装を変えてみよう。

&&で受け取ったオブジェクトのコピーをせずにポインタだけコピーしている。nameの方はNULLをセットしてデストラクタが呼ばれても大丈夫なようにしている。

と思ったが上のコードにはひとつ問題が。ある?
thisと&&が同じ場合のときを考えていなかったがそんなことはあるだろうか?ここではないとしてスルー

std::move()

上記の例は全部コンパイラが勝手に呼んでくれたものだった。
コンパイラは死ぬだけになったオブジェクトを判別できれば呼んでくれるが、すべてのものを判別できるとは限らない。

4行目のn1はもう使ってないので&&を呼んでくれてもいいのに呼んでくれない。そこで書き換えよう。

ここまで全部のソース

std::moveはよっぽど特殊じゃないと使わない気がするし間違うとやばい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です