この問題の歴史:
ポインタはC++の主要なツールの1つであり、言語の登場以来、メモリ管理や動的データ構造の基盤として、また低レベルシステムライブラリとの相互作用のために使用されています。参照は後に追加され(C++の登場とともに)、構文を簡素化し、コードの安全性を高めるために導入されました。
問題:
メモリを扱う際のエラーはC++で最も一般的な問題の1つであり、特にポインタの誤った使用(ダングリングポインタ、メモリリーク)によって引き起こされます。初心者は、参照を使用すべき場合とポインタを使用すべき場合が分からなかったり、それらが完全に相互に置き換え可能であると誤解したりすることがあります。
解決策:
ポインタ(T*)は、オブジェクトのアドレスを保存する変数であり、nullptrになり得ます。算術演算をサポートし、動的なメモリの割り当てと解放を許可し、指し示す先を変更できます。
参照(T&)は、別の既存のオブジェクトのエイリアスです。参照は作成時に初期化される必要があり、「空」であること(nullを参照すること)はできず、算術演算をサポートしませんが、機能に渡す際などで便利で安全です。
コード例:
void increment_pointer(int* p) { if(p) ++(*p); } void increment_reference(int& r) { ++r; } int main() { int a = 5; increment_pointer(&a); increment_reference(a); }
主な特徴:
nullptrになることができます初期化後に参照を変更して別のオブジェクトを参照させることはできますか?
できません。C++における参照は定数エイリアスです。一度初期化されると、参照は常に同じオブジェクトを指し続けますが、ポインタは再指向できます。
コード例:
int a = 1; int b = 2; int& ref = a; // ref = b - bの値を代入しますが、refは引き続きaを参照します
「ヌル」参照やnullptrを参照する参照を作成できますか?
できません。標準は存在しないオブジェクトを参照することを許可していません。これは未定義の動作を引き起こします。
例:
int* p = nullptr; // int& r = *p; - UB
int const ptr と const int ptr は何が違いますか?**
int* const ptrはintの定数ポインタ(ポインタを再指向できませんが、値は変更できます)。const int* ptrは定数intへのポインタ(指している内容を変更できませんが、ポインタを再指向できます)。
コード例:
int a = 1, b = 2; const int* ptr1 = &a; // *ptr1は変更できませんが、ptr1 = &bは可能 int* const ptr2 = &a; // *ptr2は変更可能ですが、ptr2 = &bはできません
若い開発者がポインタを使用してパラメータを渡し、nullptrをチェックせずにエラー時にクラッシュしました。
プラス:
マイナス:
経験豊富な開発者が、渡すことが確実な場合にはint&を、nullptrの可能性がある場合にはint*を使用し、必ずポインタをnullでチェックしました。
プラス:
マイナス: