C++を学習していると、関数へ変数を渡す方法として「参照渡し」と「ポインタ渡し」という2つの方法が登場します。どちらも元の変数を直接変更できる仕組みですが、書き方や扱い方、適している場面には違いがあります。
この記事では、C++初心者でも理解できるように、参照渡しとポインタ渡しの基本的な仕組み、違い、どのような場合に使い分けるべきかを具体例を交えて解説します。
C++の値渡し・参照渡し・ポインタ渡しの基本
C++の関数へ変数を渡す方法には、主に「値渡し」「参照渡し」「ポインタ渡し」の3種類があります。
値渡しでは、関数へ渡す際に変数のコピーが作られます。そのため、関数内で値を変更しても元の変数には影響しません。
一方、参照渡しとポインタ渡しは、元の変数そのものへアクセスできるため、関数内で値を変更すると呼び出し元の変数も変更されます。
参照渡しとは何か?
参照渡しとは、変数の別名(参照)を関数へ渡す方法です。参照は元の変数と同じ場所を指しているため、コピーを作成せずにデータを扱えます。
参照渡しでは「&」記号を使って引数を宣言します。
#include <iostream>
using namespace std;
void changeValue(int& x){
x = 100;
}
int main(){
int num = 10;
changeValue(num);
cout << num;
}
この例では、changeValue関数内でxを書き換えると、main関数側のnumも100になります。参照は変数そのものの別名なので、ポインタのようにアドレスを意識する必要がありません。
ポインタ渡しとは何か?
ポインタ渡しとは、変数のメモリアドレスを関数へ渡す方法です。ポインタ変数を使って、元のデータが保存されている場所へアクセスします。
ポインタ渡しでは「*」や「&」を使用します。
#include <iostream>
using namespace std;
void changeValue(int* x){
*x = 100;
}
int main(){
int num = 10;
changeValue(&num);
cout << num;
}
changeValue関数へnumのアドレスを渡し、ポインタを通して値を変更しています。参照渡しと同じように、元のnumの値は100になります。
参照渡しとポインタ渡しの主な違い
参照渡しとポインタ渡しは似ていますが、重要な違いがあります。
| 項目 | 参照渡し | ポインタ渡し |
|---|---|---|
| 記述方法 | &を使用 | *と&を使用 |
| NULLを扱えるか | 基本的に扱えない | nullptrを指定できる |
| 値の変更 | 可能 | 可能 |
| アドレス操作 | 不要 | 必要 |
| 安全性 | 比較的高い | 注意が必要 |
大きな違いは、参照は必ず何かの変数を参照する必要があるのに対して、ポインタは何も指していない状態(nullptr)を持てることです。
例えば、関数に「必ず存在するデータ」を渡したい場合は参照渡しが向いています。一方、「データが存在しない可能性がある」場合はポインタ渡しが適しています。
参照渡しを使うべき場面
現在のC++開発では、特別な理由がない限り参照渡しが選ばれることが多くあります。
例えば、構造体やクラスなど大きなデータを関数へ渡す場合、コピーを作らず効率的に処理できます。
void printData(const string& text){
cout << text;
}
このようにconst参照を使うことで、データをコピーせず読み取り専用として扱うこともできます。C++では非常によく使われる書き方です。
ポインタ渡しを使うべき場面
ポインタ渡しは、メモリアドレスを直接扱う必要がある場合に利用されます。
例えば、動的メモリ管理、配列操作、C言語との連携、データが存在しない状態を表現したい場合などではポインタが便利です。
例として、関数の結果として「成功した場合だけ値を返したい」という処理では、nullptrを利用できるポインタが役立つ場合があります。
C++初心者が混乱しやすいポイント
参照渡しとポインタ渡しが混同されやすい理由は、どちらも元の変数を変更できるためです。
しかし、考え方としては「参照は別名」「ポインタは住所を持つ変数」と考えると理解しやすくなります。
例えば、友人に直接荷物を渡すイメージが参照渡し、荷物が置いてある場所の住所を教えるイメージがポインタ渡しです。
まとめ:参照渡しとポインタ渡しは目的によって使い分ける
C++の参照渡しとポインタ渡しは、どちらも元のデータへアクセスするための仕組みですが、用途が異なります。
通常の関数引数では、安全で扱いやすい参照渡しが選ばれることが多く、アドレス操作やnullptrのような状態を扱う必要がある場合にはポインタ渡しが利用されます。
「参照は変数の別名」「ポインタはメモリアドレスを扱うもの」という基本を理解すると、C++の関数引数の仕組みをより深く理解できるようになります。


コメント