関数への値渡しの種類~値渡し・ポインタ渡し・参照渡し~

pass-by-v-p-r-e プログラミング

※当ブログでは商品・サービスのリンク先にプロモーションを含みます。ご了承ください。

C++プログラムを書いていて、関数の引数ってどういう形で渡すのがいいのかいまいちわかってませんでした。

結論でいうと、参照渡しが一番いいんですね〜ってことで。それぞれを簡単にまとめたいと思います。

値渡し

値をそのまま渡す方法になります。なので、値が新しくコピーされて、関数に渡っていきます。

新しくコピーされるので、その値分新たにメモリを確保する必要があります。

これを使う時は、組み込み型の型(int, float, doubleなど)を引数に指定するときとのこと。

そんなにサイズも大きくないし、メモリを圧迫しないことを考えると納得です。

void hello(int a){
  ...
}

ポインタ渡し

メモリアドレスを渡す方法になります。

メモリアドレスを渡すだけなので、値渡しと違って、新たにメモリを確保しなくてもよくなりますね。

ただメモリアドレスを触るということは、元の変数も触ることになるので、危ないです。

constを使って変更不可の対策を立てた方が良いです・・が、ポインタ変数のconstはちょっとややこしいので、別記事にまとめます。

void hello(int const* const a){
  if(a === nullptr){
    ...
  }
  
  cout << *a << endl // 123
  ...
}

int main(){
  int num = 123;
  hello(&num);
}

ちなみにポインタ渡しだと、null対策をする必要があります。

ポインタはnullを取ることがあるためです。

参照渡し

ポインタ渡しの便利バージョンです。

基本的に内容はポインタ渡しと同じなんですが、書き方が少し簡単になります。

void hello(const int &a){
  cout << a << endl // 123
  ...
}

int main(){
  int num = 123;
  hello(num);
}

ポインタ渡しと比べて、

  • 関数呼び出し時に&(参照演算子)をつけなくてよい
  • 関数内で、*(間接演算子)を操らなくて良い
  • 関数内でnull対策をしなくてよい

というように、ポインタ渡しと比べるとメリットが多いです。

参照渡しでは、値の入っている変数を受け取るので、nullをとることがまずない、ということなのです。

まとめ

C++における、値渡し・ポインタ渡し・参照渡しを解説しました。

結論からいうと、サイズの小さい引数は値渡し、それ以外は参照渡しにするのが無難かなと思いました。

にほんブログ村に参加しております!よろしければクリックお願いします 🙂

にほんブログ村 IT技術ブログへ
にほんブログ村

コメント

  1. バイクジジー より:

    参照渡しは、ポインター渡しの致命的ともいえる潜在的問題を解決するために導入されたのだと自己流に理解しています。その欠点とは、ポインターは、メモリー中のどんなアドレスも指示することができ、変更することも容易です。だから、対象としている変数でなくても、簡単に変更きてしまう。つまり、ちょっとした間違いや簡単な細工で、バグやセグメンテーションフォルトなどの意図しない重大な問題をもたらします。このような事情にあるため、通常、参照渡しは、ポインター渡しよりも、強く推奨されると考えています。

    ポインター渡しと参照渡しの挙動の違いを説明して技巧に走っている感のサイトは多いのですが、参照渡しなどの目的を解説しているサイトはあまり見かけません。目的や背景を理解できるようになると、みんなが楽しく興味を持って親しみやすくなるのではないでしょうか?

タイトルとURLをコピーしました