C++の参照型について
こちらを参考にしました。
参照型とは
変数に別名をつけて参照することが可能となるC++の機能
int x = 20; int& y = x; // yをint型への参照として定義。参照先:x y = 30; // xも30となる。
参照型を宣言するためには、宣言の前に&
をつける。
アドレス演算子の&
とは異なることに注意。
ポインタと参照型
ポインタと参照型は類似しているが、微妙に異なる。 差異としては、 * ポインタは宣言後の代入が可能だが、参照型は宣言と代入は一体(参照先は変更不可) (ポインタはアドレスを指すが、参照は変数のアドレスを指すようなもの。)
参照型を定義するときは、初期化も一緒にする必要がある。
int x; int& y; y = x; // コンパイルエラー!!!
上記の性質により、参照型は指し先があいまいになったり、nullptrを指したりすることはない。
セマンティクスとシンタックス
こちらの記事を参考にいたしました。
セマンティクスとシンタックス
セマンティクスとは、意味論を表し、シンタックスは構文を表す。
つまり シンタックス: 目的の動作を達成するプログラムを、どのように記載するかというルール セマンティクス: ソースコードがどのような意味をもっているか
言い換えると、 - シンタックス: ソースコードをどう描くか - セマンティクス:ソースコードはどう動くか
例えば、C言語において、
int a[4]; a[4] = 1;
と、
*(a + 4) = 1;
これらは、異なるシンタックスを用いてるが、同じセマンティクスとなる。
auto_ptrの非推奨理由
参考にした記事によると、C++11からauto_ptrが非推奨となった理由は、
=
を用いたシンタックスは通常コピーを表すにも関わらず、auto_ptrを用いた場合のみ、
moveのセマンティクスを持った動作をしていた。
C++11で定義されたunique_ptr
では、そもそもコピー=
が禁止となった。
右辺値と右辺値参照
こちらの記事を参考にいたしました。
右辺値と左辺値の違い
C++では、右辺値と左辺値が明確に区別される。
int i = 1;
例えば、上記ではiが左辺値, 1が右辺値となる。 左辺値は、名前付きオブジェクトであり、右辺値はすぐに破棄されるもの。 右辺値として、コンストラクタや関数の戻り値などがある。
右辺値は、基本的に評価された時点で破棄される。 そのため、左辺値を定義しないコンストラクタの戻り値は、関数を抜ける前に破棄される。
class something{ public: ~something() { printf("something destructor"); }; } int main () { something(); // この時点でprintされる(関数抜ける前に!!) printf("after something") return 0; }
実行結果は以下のようになる
something destructor after something
一方で、Object a
のような名前付きオブジェクトを左辺値という。
左辺値はスコープを抜けるまで破棄されない。
右辺値参照
右辺値のスコープをのばすには、右辺値参照というものを用いる。
int&& a = 10;
右辺値参照型はT&&
で定義できる。
右辺値参照型は左辺値のため、右辺値は、スコープを抜けるまで破棄されないことになる。
左辺値を右辺値にキャストする
std::move
を用いると、左辺値を右辺値にキャストできる。
これがムーブセマンティクスを表現するシンタックスのひとつとなる。
これは、値のコピーをしたくない場合に、所有権を奪うときに使用したりする。