©️

C++ 参照渡し・参照戻し

2024/10/04に公開

参照渡し

C言語で、関数の引数にポインタを渡し、関数のなかで値を書き換えるようなことを、C++では参照渡しでも実現できる

値渡しと参照渡しの多重定義はできない

int func(int a, int b);
int func(int &a, int &b);
/* ... */
int main() {
    int x = 10, y = 20;
    // エラー:オーバーロードされた関数 "func" の複数のインスタンスが引数リストと一致します
    int z = func(x, y);
    /* ... */
}

サンプルコード

#include <iostream>

// 参照渡し
void refSwap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

// ポインタ渡し(C言語)
void pointerSwap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 10, y = 20;

    // 参照渡し
    refSwap(x, y);
    std::cout << "x: " << x << ", y: " << y << std::endl;  // 出力: x: 20, y: 10

    // ポインタ渡し
    pointerSwap(&x, &y);
    std::cout << "x: " << x << ", y: " << y << std::endl;  // 出力: x: 10, y: 20

    return 0;
}

参照戻し

戻り値で参照を返す
参照を返すので、新たにメモリを確保しない

戻り値の型だけで識別される関数は多重定義できない

// エラー:戻り値の型だけで識別される関数はオーバーロードできません
int& func(int &a, int &b);
int func(int &a, int &b);

サンプルコード

#include <iostream>

// 参照戻しの関数(&を付ける)
int& refElement(int arr[], int index) {
    return arr[index];  // 配列要素への参照を返す
}

// ポインタで戻す(C言語)
int* pointerElement(int arr[], int index) {
    return &arr[index];  // 配列要素へのポインタを返す
}

int main() {
    int myArray[5] = {10, 20, 30, 40, 50};

    // 関数から参照を取得し、その値を変更
    refElement(myArray, 2) = 100;  // myArray[2]に新しい値を代入(refElement(myArray, 2) == &myArray[2])

    // ポインタを取得し、実体の値を変更
    int* ptr_ele = pointerElement(myArray, 3);
    *ptr_ele = 200;

    // 配列の内容を表示
    std::cout << "Updated array: ";
    for (int i = 0; i < 5; ++i) {
        std::cout << myArray[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

実行結果

Updated array: 10 20 100 200 50

Discussion