HOWTO · C++

C++ における *& と **& の機能と違い

このガイドでは、C++ の *& と **& の違いと機能について学習します。

このガイドでは、C++ における *&**& の違いと機能について説明します。 これらのシンボルを理解するには、C++ のポインターの概念に精通している必要があります。

したがって、先に進んでガイド全体を読む前に、ポインターに関する ガイド にアクセスしてください。 この概念を理解すれば、このガイドを理解するのは簡単です。

C++ における *&**& の機能と違い

ポインターで値を処理する場合は、ポインターを使用します。 その構文は *ptr です。

次の例を参考にして、この概念全体を理解しましょう。

#include <iostream>
using namespace std;

// global variables
int value_1 = 10, value_2 = 20, *global_ptr;

value_1value_2 という 2つの変数と、*global_ptr として 1つのグローバル ポインターを作成するだけです。 次に、すべてを明確にするために、3つの異なる関数とメソッドを作成しました。

それらの機能は以下の通りです。

C++ でのポインターによる値の処理

// function which handles values by pointer
void byPointer(int *ptr) {
  *ptr = 5;
  ptr = global_ptr;
  *ptr = 3;
}

最初の関数は、パラメーターがポインターであることがわかるように、ポインターによって値を処理します。

内部では、単にポインターの値をオーバーライドし、それをグローバル ポインターにポイントし、後でその値を再度オーバーライドしています。 main() 関数を見てみましょう。

int main() {
  // a pointer to value 1
  int *ptrValue_1 = &value_1;

  // a global pointer having an address of value 2

  global_ptr = &value_2;

  // values before calling function
  cout << "Value_1 = " << value_1 << endl;
  cout << "Value_2 = " << value_2 << endl;

  cout << "ptrValue_1 = " << ptrValue_1 << endl;
  cout << "global_ptr = " << global_ptr << endl;

  byPointer(ptrValue_1);

  // values after calling function
  cout << "Value_1 = " << value_1 << endl;
  cout << "Value_2 = " << value_2 << endl;

  cout << "ptrValue_1 = " << ptrValue_1 << endl;
  cout << "global_ptr = " << global_ptr << endl;
  return 0;
}

最初に、最初の変数のアドレスを指すポインターを作成しました。 グローバル ポインターは、2 番目の変数のアドレスを指しています。

変数 value_1value_2 の初期値がそれぞれ 10 と 20 であることがわかるように、ポインター ptrValue_1 を上記の関数に渡すだけです。

ただし、関数 byPointer() 内では、これらの値はオーバーライドされます。 ポインターは、value_2 のアドレスを指しているグローバル ポインターのアドレスも指しています。 そのため、両方の値が変更されました。

上記のコードの出力は次のとおりです。

Value_1 = 10
Value_2 = 20
ptrValue_1 = 0x4b8000
global_ptr = 0x4b8004
Value_1 = 5
Value_2 = 3
ptrValue_1 = 0x4b8000
global_ptr = 0x4b8004

ご覧のとおり、両方の変数の値が変更されていますが、ポインターのアドレスは変更されていません。 これは、ポインタのコピーを作成し、このような値の処理方法でコピーを使用して値を処理するためです。

そのため、アドレスは変更されません。 この概念は、理解を深めるのに役立ちます。

C++ での参照ポインターによる値の処理

それでは、C++ の *& の概念を理解しましょう。 次のコードを見てください。

// function which handle values by pointer Reference
void byPointerReference(int*& ptr) {
  *ptr = 40;
  ptr = global_ptr;
  *ptr = 50;
}

上記のメソッドでは、ポインターへの参照をパラメーターとして渡します。 ポインターを渡した関数と同じように機能します。

唯一の違いは、ポインターのアドレスも変更されることです。 メソッドの後、ポインターのアドレスは、このコードによるとグローバル ポインターのアドレスと同じになります。

int main() {
  // a pointer to value 1
  int *ptrValue_1 = &value_1;

  // a global pointer having the address of value 2

  global_ptr = &value_2;

  // values before calling function
  cout << "Value_1 = " << value_1 << endl;
  cout << "Value_2 = " << value_2 << endl;

  cout << "ptrValue_1 = " << ptrValue_1 << endl;
  cout << "global_ptr = " << global_ptr << endl;

  byPointerReference(ptrValue_1);

  // values after calling function
  cout << "Value_1 = " << value_1 << endl;
  cout << "Value_2 = " << value_2 << endl;

  cout << "ptrValue_1 = " << ptrValue_1 << endl;
  cout << "global_ptr = " << global_ptr << endl;
  return 0;
}

ここでの考え方は、アドレスとポインターの値の両方が変化することを示すことです。 上記のコードの出力は次のとおりです。

Value_1 = 10
Value_2 = 20
ptrValue_1 = 0x4b8000
global_ptr = 0x4b8004
Value_1 = 40
Value_2 = 50
ptrValue_1 = 0x4b8004
global_ptr = 0x4b8004

C++ でのポインター参照 (ダブルポインター) へのポインターによる値の処理

単一のポインター参照と同じように機能します。 唯一の違いは、ダブルポインターであることです。

たとえば、ギフトを 1つの箱に詰めて、同じギフトを同じ箱に詰めると、最終的に相手がギフトを受け取ります。 違いはありません。

唯一の違いは構文にあります。 二重ポインタ参照は次のようになります。

int **ptrToptr = &ptrValue_1;

関数/メソッドを見てみましょう。

void bypointerPointerReference(int**& ptr) {
  **ptr = 40;
  *ptr = global_ptr;
  **ptr = 50;
}

構文以外に違いはありません。 主な機能は以下になります。

int main() {
  // a double pointer to value 1
  int *ptrValue_1 = &value_1;
  int **ptrToptr = &ptrValue_1;

  // a global pointer having an address of value 2

  global_ptr = &value_2;

  // values before calling function
  cout << "Value_1 = " << value_1 << endl;
  cout << "Value_2 = " << value_2 << endl;

  cout << "ptrValue_1 = " << ptrValue_1 << endl;
  cout << "global_ptr = " << global_ptr << endl;
  bypointerPointerReference(ptrToptr);

  // values after calling function
  cout << "Value_1 = " << value_1 << endl;
  cout << "Value_2 = " << value_2 << endl;

  cout << "ptrValue_1 = " << ptrValue_1 << endl;
  cout << "global_ptr = " << global_ptr << endl;
  return 0;
}

出力は上記のものと同じになります。

Value_1 = 10
Value_2 = 20
ptrValue_1 = 0x4b8000
global_ptr = 0x4b8004
Value_1 = 40
Value_2 = 50
ptrValue_1 = 0x4b8004
global_ptr = 0x4b8004