Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C++

C++の値渡しと参照渡しの使い分けや違いについて

投稿日:2021年1月13日 更新日:

<目次>

(1) C++の値渡しと参照渡しの使い分けや違いについて
 (1-1) 「値渡し」とは?
 (1-2) 「参照渡し」とは?
 (1-3) 「値渡し」と「参照渡し」の使い分け

(1) C++の値渡しと参照渡しの使い分けや違いについて

「値渡し」(passed by value)と「参照渡し」(passed by reference)はメソッドを実行する際の「引数の与え方」の方式です。今回はそれぞれをどういったシーンで使うのか?や両者の違いについてご紹介していきます。

(1-1) 「値渡し」とは?

引数の「値のコピー」をメモリ上の別アドレスに作っています(元の値とは明確に異なる)。

コピーなので「呼び出し元」と「呼び出し先」とで、同じ値だがそれぞれ独立した変数を持っている事になります。従って、「呼び出し先」で値を変更しても、「呼び出し元」の値は書き換わりません(コピーを編集しているに過ぎない)。

(図113)

デフォルトでは「値渡し」が適用されます(型の後に&を付けると「参照渡し」になる)。

(サンプルプログラム)

#include <iostream>
using namespace std;

//③引数を「値渡し」で受取り⇒値がメモリ上の別箇所にコピーされる
void addCounter(int counter)
{
    //④引数の値に1を加算(値渡しなので、元の変数に影響なし)
    counter=counter+1;
    std::cout<<"(#1)= "<<counter<<std::endl;
}

int main(void){
    //①変数「counter」を定義
    int counter=0;
    //②変数「counter」を「addCounter」関数の引数に与えて実行
    addCounter(counter);
    //⑤元の変数は加算されていないので「0」
    std::cout<<"(#2)= "<<counter<<std::endl;
    return 0;
}

(図121)実行結果

目次にもどる

(1-2) 「参照渡し」とは?

引数の「アドレス」を渡しており、変数自身の「アドレスのコピー」(=ポインタ)をメモリ上に作っています。別名「アドレス渡し」とも呼ばれます。

「アドレス」を渡しているので、「呼び出し元」と「呼び出し先」とで同じ値を共有しており、「呼び出し先」で引数に変更を加えた場合は、呼び出し元にも反映されます。

(図114)

C++では引数の左側に「&」を付ける事で、参照渡しになります(右側に付けてしまうと別の意味になってしまう)。
(サンプルプログラム)

#include <iostream>
using namespace std;
//③引数を「参照渡し」で受取り⇒アドレスがメモリ上の別箇所にコピーされる
void addCounter(int &counter)
{
    //④参照渡しなので元の変数を更新
    counter=counter+1;
    std::cout<<"(#1)= "<<counter<<std::endl;
}

int main(void){
    //①変数「counter」を定義
    int counter=0;
    //②変数「counter」を「addCounter」関数の引数に与えて実行
    addCounter(counter);
    //⑤元の変数は参照渡しにより、同じく「1」
    std::cout<<"(#2)= "<<counter<<std::endl;
    return 0;
}

(図122)実行結果

目次にもどる

(1-3) 「値渡し」と「参照渡し」の使い分け

「値渡し」は引数として渡された値を上書きしないため、値を「利用するだけ」で更新は特に必要ない場面で使用します。また、値コピー時のオーバーヘッドによりパフォーマンス悪化につながる可能性がありますので、注意が必要です(大規模なオブジェクトを値渡しして、かつそのメソッドを何度も繰り返し呼ぶ場合など)。

「参照渡し」は変数のコピーを作成しないため、コピー処理によるオーバーヘッドが削減されます。

引数で大規模なテキストデータなどが渡されると、そのコピーの処理は負荷となるため、避けるべきものになります。そういった大規模なクラスのオブジェクトを渡す際などに「参照渡し」が役に立ちます。

「参照渡し」を使う主なシーンを4点ほど挙げます。
(表)

①引数の編集 関数の処理で「引数を編集」する必要がある場合
②引数が大規模オブジェクト 関数の引数に「大規模なオブジェクト」を受け取る場合
⇒値渡しだとコピーの処理負荷が発生してしまう
③ポリモフィズム ポリモフィズム(同じ操作でも異なる振る舞いをする事)を実現する場合。
(例)
「図形クラス」があったとして、それを継承する「三角形クラス」と「四角形クラス」があった際に、「図形」型のポインタ(別の値のアドレスを保持)に「三角形」や「四角形」の「参照(アドレス)」を渡す事で、親のメソッド等の実行結果を、子でも利用する事などが可能になります。
④戻り値が大規模 「戻り値」として非常に大きなオブジェクトを返却する恐れがある場合

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-C++

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

C++の「->」(アロー演算子)とは?意味や使い方をご紹介

  <目次> (1) C++の「->」(アロー演算子)とは?意味や使い方をご紹介  (1-1) C++の「->」(アロー演算子=arrow operator)とは?  (1-2) …

C++をLinuxでコンパイルする方法について

  <目次> (1) C++をLinuxでコンパイルする方法について  (1-1) STEP0:【事前準備】ターミナル機能の準備(ターミナル、Teraterm、Putty)  (1-2) S …

C++の構造体とは?の作り方や使い方について

  <目次> (1) C++の構造体とは?の作り方や使い方について  (1-1) 構造体とは?  (1-2) サンプルプログラム  (1-3) 構造体の変数を定義する方法  (1-4) 構造 …

no image

C++のマルチスレッド処理のサンプルや概要について

  <目次> (1) C++のマルチスレッド処理のサンプルや概要について  (1-1) C++のマルチスレッドの概要  (1-2) 構文1:関数ポインタ式  (1-3) 構文1(例):関数ポ …

C++の共用体とは?構造体との違いや使用方法について

  <目次> (1) C++の共用体とは?構造体との違いや使用方法について  (1-1) 共用体とは?構造体との違いは?  (1-2) 共用体の定義方法、変数定義方法、初期化方法  (1-3 …

  • English (United States)
  • 日本語
Top