C++におけるポインタ変数と参照変数の違い
ポインタ変数と参照変数は、どちらも他の変数のメモリアドレスを保持するという意味で似ています。しかし、その使用方法や特性にはいくつかの重要な違いがあります。
ポインタ変数
- 宣言方法:
データ型 *変数名;
- 値: 変数のアドレスを保持する。
- 操作:
- アドレスの変更が可能。
*
演算子を使って間接参照が可能。->
演算子を使って構造体やクラスのメンバにアクセス可能。
- NULLポインタ:
NULL
値を保持することができる。 - 用途: 動的なメモリ管理、関数への引数の渡し、データ構造の実装など。
参照変数
- 宣言方法:
データ型 &変数名 = 対象変数;
- 値: 対象変数のエイリアスとして動作する。
- 操作:
- アドレスの変更はできない。
- 対象変数の値を変更すると、参照変数の値も変更される。
.
演算子を使用して対象変数のメンバにアクセス可能。
- NULL参照:
NULL
値を保持できない。 - 用途: 関数への引数の渡し、クラスのメンバー関数の実装など。
- ポインタ変数: 柔軟性が高く、アドレスの操作が可能。
- 参照変数: 対象変数のエイリアスとして動作し、アドレスの変更はできない。
例:
int x = 10;
int *p = &x; // ポインタ変数 p に x のアドレスを格納
int &r = x; // 参照変数 r を x のエイリアスとして宣言
*p = 20; // p を使って x の値を変更
r = 30; // r を使って x の値を変更
cout << x << endl; // 出力: 30
ポインタと参照の例
#include <iostream>
using namespace std;
int main() {
int x = 10;
int *p = &x; // ポインタ変数 p に x のアドレスを格納
cout << "xの値: " << x << endl;
cout << "pの値 (xのアドレス): " << p << endl;
cout << "pが指す値: " << *p << endl;
*p = 20; // p を使って x の値を変更
cout << "変更後の xの値: " << x << endl;
return 0;
}
#include <iostream>
using namespace std;
int main() {
int x = 10;
int &r = x; // 参照変数 r を x のエイリアスとして宣言
cout << "xの値: " << x << endl;
cout << "rの値: " << r << endl;
r = 20; // r を使って x の値を変更
cout << "変更後の xの値: " << x << endl;
return 0;
}
解説
ポインタ変数の例では、p
は x
のアドレスを保持しています。*p
を使用することで、p
が指すメモリ位置の値にアクセスできます。この例では、*p
を変更することで、x
の値も変更されます。
違い:
- アドレスの変更: ポインタ変数はアドレスを変更できますが、参照変数はできません。
- エイリアス: 参照変数は対象変数のエイリアスとして動作します。
- 演算子: ポインタ変数には
*
演算子を使用して間接参照を行います。参照変数には.
演算子を使用して対象変数のメンバにアクセスします。
ポインタと参照の代替方法
ポインタと参照は、C++で変数のアドレスを扱うための重要な概念です。しかし、特定の状況では、これらの代替方法を使用することもできます。
const参照
- 目的: 対象変数の値を変更できない参照を作成する。
int x = 10;
const int &r = x; // r は x の読み取り専用参照
// r = 20; // エラー: r は const 参照なので変更できません
std::reference_wrapper
- 目的: 参照を値として扱うことができるようにする。
- 宣言:
std::reference_wrapper<データ型> 変数名 = 対象変数;
int x = 10;
std::reference_wrapper<int> ref = x;
// ref.get() を使って参照先の値にアクセス
cout << ref.get() << endl; // 出力: 10
std::unique_ptr
- 目的: 自動的なメモリ管理と所有権の管理を行う。
- 宣言:
std::unique_ptr<データ型> 変数名 = std::make_unique<データ型>();
std::unique_ptr<int> ptr = std::make_unique<int>(10);
// ptr がスコープ外になると自動的にメモリが解放される
std::shared_ptr
- 目的: 複数のオブジェクトが同じメモリを共有できるようにする。
std::shared_ptr<int> ptr1 = std::make_shared<int>(10);
std::shared_ptr<int> ptr2 = ptr1;
// ptr1 と ptr2 が同じメモリを共有している
std::weak_ptr
- 目的:
std::shared_ptr
の弱参照を作成する。 - 宣言:
std::weak_ptr<データ型> 変数名 = ptr; // ptr は std::shared_ptr
std::shared_ptr<int> ptr = std::make_shared<int>(10);
std::weak_ptr<int> weak_ptr = ptr;
// weak_ptr は ptr が存在する限り有効
c++ pointers reference