⬆️
ポインタや参照の振り返り「"&", "*"」
&
と*
の概念をわかりやすく解説し、さまざまな場面での使い方について説明します。
基本的な意味
-
*
(ポインタ)- データのアドレスを保持する特殊な型。
- 例:ポインタは「他の変数が格納されているメモリの場所」を指します。
int x = 10; int *ptr = &x; // xのアドレスをポインタptrに保存
-
&
(参照)- 既存の変数へのエイリアス(別名)を作るための型。
- 例:参照は「実際の変数そのもの」として動作します。
int x = 10; int &ref = x; // refはxへの参照
-
&
(アドレス演算子)- 変数のアドレスを取得します。
- 例:
int x = 10; int *ptr = &x; // xのアドレスをポインタptrに格納
-
*
(間接演算子 / デリファレンス演算子)- ポインタが指しているアドレスの値にアクセスします。
- 例:
int x = 10; int *ptr = &x; *ptr = 20; // xの値を20に変更
関数での使用
1. 値渡し
- 引数として値そのものを渡します。
- コピーが渡されるため、関数内での変更は元の変数に影響しません。
- 例:
void modifyValue(int val) { val = 20; // valを変更しても元の変数には影響なし } int x = 10; modifyValue(x); // xは10のまま
2. 参照渡し(&)
- 引数として変数そのものを渡します。
- コピーが作られず、直接操作できるため、関数内での変更が元の変数に反映されます。
- 例:
void modifyValue(int &val) { val = 20; // valを変更すると元の変数も変更される } int x = 10; modifyValue(x); // xは20に変更される
3. ポインタ渡し(*)
- ポインタを渡し、変数を操作します。
- 参照渡しと似ていますが、ポインタの操作が必要です。
- 例:
void modifyValue(int *val) { *val = 20; // ポインタが指す変数の値を変更 } int x = 10; modifyValue(&x); // xのアドレスを渡す // xは20に変更される
戻り値での使用
-
値を返す
- 新しい値を返す方法。
- 例:
int addOne(int val) { return val + 1; }
-
参照を返す(&)
- 既存の変数そのものを返す方法。
- 元の変数を変更可能。
- 例:
int& getReference(int &val) { return val; } int x = 10; int &ref = getReference(x); ref = 20; // xも20に変更される
-
ポインタを返す(*)
- ポインタで既存の変数を返す方法。
- 例:
int* getPointer(int &val) { return &val; } int x = 10; int *ptr = getPointer(x); *ptr = 20; // xも20に変更される
オブジェクトの使用例
ポインタと参照をメンバに持つクラス
class MyClass {
private:
int value; // 通常の値
int *ptrValue; // ポインタ
int &refValue; // 参照
public:
MyClass(int v, int &r) : value(v), ptrValue(&v), refValue(r) {}
void showValues() {
std::cout << "value: " << value << "\n";
std::cout << "ptrValue: " << *ptrValue << "\n";
std::cout << "refValue: " << refValue << "\n";
}
};
ポインタ vs 参照の違い
-
ポインタ
- 初期化後でも別のアドレスを指すように変更可能。
-
参照
- 初期化時に必ず対象を設定し、後から変更できない。
間違いの具体例
以下は間違い:
void learnSpell(*ASpell &spell) const; // エラー
修正例:
void learnSpell(ASpell *spell); // ポインタ渡し
void learnSpell(ASpell &spell); // 参照渡し
どちらを使うべきか?
-
ポインタを使うべき場面:
- 可変性が必要(対象を変更可能)。
-
nullptr
を扱う必要がある場合。
-
参照を使うべき場面:
- NULLの概念が不要。
- 必ず有効な変数を操作する場合。
このように、&
と*
はポインタ、参照、アドレスの操作を可能にする重要な要素です。それぞれの役割を理解し、適切に使い分けることが重要です。
Discussion