C++プログラマ キャスブログ
[C++11]右辺値参照とムーブセマンティクス 2015年05月14日22:53:08
簡単に説明すると一時オブジェクトのポインタの所有権の移動です。 何ができるかといえば、インスタンスを返す関数のコピーコンストラクタを 走らせずに済むということができます。 効果としては、メモリ確保・解放とコピーのコストを無くせます。 あくまでポインタの所有権の移動なので、ポインタを含まないクラスのインスタンスは コピーコンストラクタと変わりありません。 コードを書くとこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <cstdio> class Test { private: int* m_Int; public: // コンストラクタ Test() { m_Int = new int; printf( "コンストラクタ: %p\n", m_Int ); } // ムーブコンストラクタ(所有権の移動に必要なコンストラクタ) Test(Test&& obj) { m_Int = obj.m_Int; // ポインタの所有権の移動 obj.m_Int = nullptr; // nullptrを入れないと多重解放になります。 printf( "ムーブコンストラクタ: %p\n", m_Int ); } // デストラクタ virtual ~Test() { printf( "デストラクタ: %p\n", m_Int ); if( m_Int != nullptr ) { delete m_Int; m_Int = nullptr; } } }; Test Instance() { Test instance; // Step.1 コンストラクタ return instance; // Step.2 ムーブコンストラクタ // Step.3 instanceのデストラクタ } int main() { Test test = Instance(); // Instance関数の中で確保したアドレスを受け取れる return 0; // Step.4 testのデストラクタ }
これでインスタンスを返す関数を作っても安心ですね。 補足情報として、自分で作ったクラスであればムーブコンストラクタの実装は可能ですが 標準ライブラリや、その他内部構造を知りたくないものについては強制的にムーブコンス トラクタを呼び出す機能があります。 それがstd::moveです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <cstdio> #include <vector> #include <utility> //std::moveに必要なヘッダ class Test { private: std::vector<int> m_Vector; public: // コンストラクタ Test() { m_Vector.resize( 1000 ); printf( "コンストラクタ: %p\n", &m_Vector[0] ); } // ムーブコンストラクタ(所有権の移動に必要なコンストラクタ) Test(Test&& obj) { m_Vector = std::move( obj.m_Vector ); // 所有権の移動 // m_Vector = obj.m_Vector; こう書くとコピーコンストラクタが走るのでダメです。 printf( "ムーブコンストラクタ: %p\n", &m_Vector[0] ); } }; Test Instance() { Test instance; return instance; } int main() { Test test = Instance(); // Instance関数の中で確保したアドレスを受け取れる return 0; }
便利ですね。 言葉ばかりややこしい右辺値参照とムーブセマンティクスですが中身は大したことないです。
カテゴリ

リンク
C++11のコードを
試すのに便利です。
http://ideone.com/

同人ゲームを
製作している知人
sorcery

にほんブログ村 IT技術ブログ C/C++へ
にほんブログ村


C++ ブログランキングへ

ゲームダウンロード DefenceTri