みゆにゃんぶろぐ

ゲーム(開発)/カラオケ/サイクリング/コーヒーの話題多め。最近は不定期更新。なるべく毎週更新したい

10月20日

最近はすっかり秋めいてきて、きんもくせいの香りもする。と同時に、気温差が激しいからか、自分のまわりでは体調を崩している人が多い。体調管理には気をつけよう

 

C++の参照

C++には参照という機能(?)がある。入学前にC++を少しかじっていた時は「CでのポインタのC++版、つまりCでいうprintf()がC++でいうcoutになったものかなぁ」なんて適当に思ってた(笑)

けど夏休みの課題あたりからC++を使うようになって、C++についてがっつり勉強してるところに、今勉強してる本に「参照」について書いてあった。そこで勉強して疑問に思ったことがあって、最近になってそれが解消されたので、自分なりにまとめておこうと思う

 

自分が参照を勉強して疑問に思っていたのは、「constつけて参照渡しすることのメリットがわからない」だった

勉強してる本には、「引数にconstをつける(=値変更しない)なら参照渡し、それ以外はポインタ渡しをしよう」的なことが書いてあった

ポインタ渡しと参照渡しの違いは以下の通りである

~ポインタ渡し~

void func_p(Test *data)

{

  // なんちゃら処理

}

~参照渡し~

void func_r(Test &data)

{

  // なんちゃら処理

}

 ここでTest型のdataというものを作った場合、func_pを呼び出すなら「func_p(&data);」となるし、func_rを呼び出すなら「func_r(data);」となる。参照渡しのほうが見た目的にすっきりしてる

でも、コードをぱっと見て「func_r(data);」で、実はdataの中身が変更できることを予想できるだろうか。参照渡ししたら、ポインタ渡しと同様に値を変更させることができる。もしかしたら、なんちゃら処理には値を変更する処理が含まれてるかもしれない

そんなわけで、値を変更しないなら「constつけて参照渡し」、変更するなら「ポインタ渡し」にして見た目的にわかりやすくしようというわけだった

けど、自分はそこで疑問に思った

実は、参照型変数のサイズは、参照元とサイズが全く同じなのだ

例えば、Test型のオブジェクトが12バイトだとしたら、Test&型も12バイトになる。ポインタであるTest*型は4バイトである

引数をポインタ渡しすることのメリットの1つに、「渡すコピー量が4バイトで済む」がある。ポインタはどんな型であっても4バイトだ。ポインタ変数にはメモリのアドレスが入ってるのだから、それを表すなら4バイトで十分だからだ。もちろん環境によっては違うかもしれない

ポインタ変数は4バイトでいいのに、参照型変数は12バイト。「参照渡ししたら値渡しの時とコピーサイズが全く同じで意味ない。しかも、constつけたら値変更もできないから、そもそもconstつきで参照渡しすることのメリットが全くないじゃん」と自分は思った。だから、本に書いてあることを疑問に思った

そんな疑問に対して調べてみたら、わかったことがあった。なんと参照渡しは裏ではポインタ渡しと同じことが行われてるというのだ。なので、コピーサイズも4バイトで済むというポインタ渡しと同じメリットを受けられる。しかもコードの見た目もスッキリする

……けど、ほんとに参照渡しの裏側でポインタ渡しと同じことがされてるのか実際に確認してないから疑問なのが本音(笑)

でもこれでとりあえずは疑問が解消された、かな