ポインタと参照
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 13/104。
stack メモリと heap メモリを理解したところで、メモリ位置を直接操作できるツール、つまりpointersとreferencesについて見ていきましょう。
pointerは別の変数のmemory addressを格納します。*で宣言し、&を使ってaddressを取得します。
int value = 42;
int* ptr = &value; // ptr は value のアドレスを保持する
std::cout << ptr; // メモリアドレスを出力する
std::cout << *ptr; // デリファレンス: 42 を出力するreference は既存の変数の alias です。一度バインドされると、常にその変数を参照します。& を使って宣言します。
int value = 42;
int& ref = value; // ref は value のエイリアスです
ref = 100; // value を 100 に変更します
std::cout << value; // 100 を出力します主な違い:
| ポインタ | 参照 |
|---|---|
| null にできる | 初期化する必要がある |
| 再代入できる | 再バインドできない |
* を使用して値にアクセスする | 値に directly アクセスする |
| 何も point できる | 常に有効 |
どちらも、コピーせずにオブジェクトを効率的に関数へ渡したり、ヒープに割り当てられたメモリを扱ったりするために不可欠です。reference はより安全で簡単ですが、再代入したり null かどうかを確認したりする必要がある場合は、pointer のほうが柔軟性に優れています。
チャレンジ
簡単データを変更する際に pointer と reference がどのように異なる働きをするかを示す、シンプルな値操作システムを構築しましょう。
コードを整理するために、2つのファイルを作成します。
ValueOps.h:整数値をさまざまな方法で変更する3つの関数を define します。doubleByPointer(int* ptr):pointer を受け取り、それが指す値を doubles しますtripleByReference(int& ref):reference を受け取り、その値を triples しますswapValues(int* a, int* b):2つの pointer を受け取り、それらが指す値を入れ替えます
main.cpp:input から2つの整数を読み取り、pointer と reference の両方を使う方法を示します。- Original の値を Print します:
"Original: <first> <second>" - 最初の値に
doubleByPointerを使用し、その後 Print します:"After double: <first>" - 2番目の値に
tripleByReferenceを使用し、その後 Print します:"After triple: <second>" swapValuesを使用して両方の値を入れ替え、その後 Print します:"After swap: <first> <second>"
- Original の値を Print します:
pointer を使って関数を呼び出すときは、変数のアドレスを渡すためにアドレス演算子(&)を使用することを忘れないでください。reference はより自然に機能するため、変数を directly 渡すだけで構いません。
#include "ValueOps.h" を使用して、header file を main.cpp に include します。
自分で試してみよう
#include <iostream>
#include "ValueOps.h"
using namespace std;
int main() {
// 入力から2つの整数を読み取る
int first, second;
cin >> first;
cin >> second;
// 元の値を出力する
cout << "Original: " << first << " " << second << endl;
// TODO: firstの値にdoubleByPointerを使う(&を使ってアドレスを渡す)
// TODO: 2倍した後に出力する
// TODO: secondの値にtripleByReferenceを使う(変数を直接渡す)
// TODO: 3倍した後に出力する
// TODO: swapValuesを使って両方の値を交換する(&を使ってアドレスを渡す)
// TODO: 交換後に出力する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタパラメータ付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ徹底解説Rule of Three / Five / Zero復習 - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () の演算子オーバーロード型変換演算子復習 - Matrixクラス自分で練習してみよう: C++オンラインコンパイラ