プラダの鞄を手渡しするのが、「値渡し」なのはOKとして、
新作プラダが売っていたら、と教えるのが「参照渡し」なのは、納得がいか~んッ!!!
ということで、図解。
話題にしたのは、PHP なんだろうけど、ちょっと C++ で図解。
PHP 版、C# 版も後ほど、作ります?
■直接、手渡せば「値渡し」
値渡しってのは、実は、コピーが発生するので、あまり正確ではないのだが、
こんな感じ。
struct Prada prada ;
Alice.Plesent( prada );
な感じですね。
実は、C++ の場合は、変数のコピーがスタック上で渡されるので、下図のようになるのが本当です。
■予約券渡して、参照渡し
そんなもののだから、一度、こっちで購入して(newして)、ポインタだけ渡します。
これが参照渡し。C#やJavaだと、これがデフォルトですね。
Prada *prada = new Prada();
Alice.Plesent( prada );
こんな感じ。ルイスは、鞄を買うわけですね。後で、取りに来て具合。
後に取りに来るにしても、new した場合は、アリスは百貨店に取りに行くわけですが、ルイスとしては自分の処に取りに来て欲しいわけで、
Prada prada;
Alice.Plesent( &prada );
とすると、自分のところに取りに来てくれます。
■レンタル品も、参照渡しで
ところで、高級品はレンタルでもいいんじゃないか、とか。
皆で共有すればいいんじゃない?ってな考え方もありますよね。
Prada *prada = new Prada();
Alice1.Plesent( prada );
Alice2.Plesent( prada );
Alice3.Plesent( prada );
確保した鞄を、それぞれのアリスに予約券で配ります。
いらなくなったら、ってな話は、C++の場合大変なのですが、C#やJavaの場合はGC(ガベージコレクション)ですね。
逆に言えば、誰かが使っている間はプラダは確保されます。
■おねだりは、参照渡しで
参照渡しのもうひとつの使い方が、おねだりパターンです。
ええ、訳が分かりませんね。図解します。
これが欲しい、とルイス君に言うと買ってくれます。
コードにすれば、
Prada *prada ;
Lewis.Onedari( &praga );
こんな風になります。
Onedari メソッドを呼ぶと、prada の中身をくれます。
たまに買ってくれないとき(nullのとき)があるので、注意が必要ですが。
■空箱を渡すと例外が発生する
ちなみに、参照渡しをするときに、nullポインタを渡すとエラーになりますね。
Prada *prada = null;
Alice.Plesent( prada );
箱を開けて見れば、空っぽッ!!、Alice は大激怒です。
そんな訳で、呼び出された側でも null チェックは必要ですよね。
ええ、元ネタは、これということでw
まちがった、
Alice.Onedari( &prada );
ですね。