関数と参照
自動的にアドレスを渡す
以前、参照の宣言方法と基本的な使い方について扱いました
今回は、参照の実用方法について触れたいと思います
一般的な参照の利用方法は、関数へのアドレスの受け渡しです
C言語では、関数内で呼び出しもとの変数や構造体のないようを更新するには
前章で説明したように、参照渡しでアドレスを明示的に渡す必要がありました
たしかにこの方法でもよいのですが、関数を使う側にしてみれば少し面倒です
その関数が値を受け取るものなのか、ポインタを受け取るものなのかを意識しなければいけません
C++では、関数にアドレスを渡すという作業をブラックボックス化することができます
こうすれば、関数の利用者は目的のデータを渡せばよいだけです
そのためには、関数の仮引数で参照を受け取るというようにします
参照を受け取るようにすれば、呼び出し側は変数を渡すだけで目的のアドレスを渡せるのです
#include <iostream>
using namespace std;
class Kitty{
public:
char *str;
};
void setKitty(Kitty &obj , char *str) {
obj.str = str;
}
int main() {
Kitty obj;
setKitty(obj , "Kitty on your lap");
cout << obj.str;
return 0;
}
setKitty()関数の第一引数では、Kittyクラスのオブジェクトの参照を受け取ります
ポインタならば setKitty(&obj , str); というように、明示的にアドレスを渡す必要がありましたが
参照の場合は、main()関数内の setKitty() の呼び出しをみてのとおり、オブジェクトを渡すだけです
参照はポインタではなく、同一のアドレスを表す別名であるということを忘れないでください
オブジェクトのメンバの参照は、アロー演算子ではなく通常のドット . を用います
この方法はオブジェクトに限ったものではなく、通常のデータ型の受け渡しにも使えます
ポインタを用いるか参照を用いるかは、プログラマの好みですが
Cプログラマの場合、今までどおりポインタを用いるプログラマが多いのも事実です
参照を返す
以外と、関数から戻り値として参照を返すと非常に面白いことができます
もっとも便利なのがメンバ関数から、プライベートエリアのデータの参照を返すというものです
関数から戻り値として参照を返す場合、戻り値の型に & 記号を指定します
type & function-name();
通常は、オブジェクトのプライベートエリアへのアクセス用インターフェイスとして
setValue() と getValue() というような、アクセス用関数を二つ用意するものです
ところが、参照を用いることでこの動作を一つの関数にまとめられます
ただし、セキュリティにおいては参照から自由にアクセスできるようになることに注意してください
#include <iostream>
using namespace std;
class Kitty{
int X;
public:
int & getX();
} obj ;
int & Kitty::getX() {
return X;
}
int main() {
obj.getX() = 10;
cout << obj.getX();
return 0;
}
Kittyクラスのメンバ関数 getX() は、プライベートエリアの X 変数の参照を返します
すなわち getX() の戻り値から変数 X にアクセスすることが可能です
参照は変数のアドレスを返すものなので、当然ローカル変数は戻り値として渡せません
ローカル変数の参照を返した場合、関数が終了すると同時にローカル変数が破棄されるため
その変数の参照も無意味なものになってしまうためです