2014年11月24日

C++ メモランダム (reference)

今日、11 月 24 日はフレディ・マーキュリーの命日でしたね。もう 20 年以上も経過しています。
そういえば、少し前にブライアン・メイを見ました。テレビだったか動画サイトだったか忘れましたが何かのインタビューだったと思います。内容も覚えてないですが、ただ「だいぶ老けたな」と思いました。フレディ・マーキュリーが生きていたら、どんな感じになっていたでしょうかね。

C++ で利用できる参照型 (reference) X& は非常に便利で、特にヌル参照が発生しにくいという利点があるのですが、発生がゼロになるというわけでもなくて、例えば

void test( const int& p )
{
  std::cout << p << std::endl;
}

int main( int argc, char* argv[] )
{
  int* i = 0;
  test( *i );
}

と書いてもコンパイルはできてしまい、実行結果は segmentation fault になります。一時期、参照ならヌル参照は絶対発生しないと思い込んでいた時期がありました。それから、ポインタの参照渡しは

int& *p

ではなく

int* &p

と書きます。前者は「参照へのポインタ」で定義不可能、後者は「ポインタへの参照」を意味します。これ、いつも逆に思えて混乱します。

参照の使い方としては、

int a = 5;

int& ref_of_a = a; // a への参照

int* pnt_of_a = &a; // a へのポインタ

int* &ref_of_p = pnt_of_a; // pnt_of_a への参照 ( = a へのポインタへの参照 )

int* pnt_of_r = &ref_of_a; // ref_of_a へのポインタ ( = a へのポインタ )

くらいを整理しておけば大丈夫でしょうか。ちなみに参照はエイリアス(別名)という意味なので実体がありません。なので、参照へのポインタというのは定義不可能ということになります。また、初期化も必ず必要です (別名にするものを渡さないと初期化できないためです)。