妹、まだ参照がわかってなかった
「じゃあ関数の話を……」
妹「ちょっと待っておくれ。冷静に考えたところ、昨日のやつがやっぱりわかってない。わかってないことがわかった」
「えー」
妹「わかったところもあるけど、いくつか釈然としないところがある」
「どのあたりが」
妹「図が抜けてたりしたのは後で直してもらうとして……そもそもの発端は、UE4で言ってる参照というのがC++のと同じ意味の参照なのか、それとも一般的な用語としての参照なのか、そのへんがあいまいで気になったんだよ」
「ブループリントの参照の方はC++との同じ。アセットの方は微妙だけど、ファイルも含んでるから、全く同じではない」
妹「じゃあ一般的な言葉で言う参照なのか?」
「一般的……うーん、一般的といえば一般的なんだけど、考え方が同じだからポインタの場合にもその言葉を使っているわけで……」
妹「あとポインタは出てきたけどアドレスの話が出てこなかった」
「UE4にはアドレス出てこないから」
妹「前に読んだ本では、ポインタだと元のデータが変わっちゃうけど、アドレスだと変わらないって書いてあったんだけど……」
「えっ!? そんなことはないと思うんだけど。見間違いとかじゃない?」
妹「図書館で借りたやつだし、もう返しちゃったからうろ覚えだけど。そのアドレスを使えば色々解決するんじゃないかと」
「アドレス……うーん、じゃあ、その話からするか。もうこれ本当にUE4関係ないな……」
妹「関係あるかどうかじゃない! わたしが釈然とするかしないかの問題なんだよ!」
「まず、パソコンのメモリってあるでしょ。レイヤたくさん使った絵を描く時とかに必要な」
妹「メモリが足りないとか何とか聞いたことはある」
「データを記憶しておくところ。お絵かきなら絵のデータが、音楽ソフトなら楽譜とか音色とかのデータが入っている」
妹「ふむふむ」
「でも絵のデータをメモリのどこに保存してるかは、その時々で違う。上の方にあるのか、下の方にあるのか…右か左かもしれないけど」
妹「なんでそんなあいまいな」
「パソコンによってメモリの量違うし、絵の大きさとかレイヤの枚数とかも違うから」
妹「じゃあどうやって動いてるのだ?」
「コレぐらいの容量が要るから用意してくれーとパソコンの方に連絡して、パソコンの方でメモリの中に空いてるとこ探して確保してくれる。ブラウザとかセキュリティのソフトとかにもメモリは必要だから、それぞれが要る分だけ注文して、その状況に応じて使える場所が変わる。要らなくなった時もまた連絡して、他で使えるようにしてもらう」
妹「メモリが足りなくなったら?」
「注文した側かパソコンか、どっちかが正常に動かなくなる。いったんリセットする電源を切るとメモリが空っぽの状態に戻るから、その状態からやり直すしかない」
妹「毎回場所が違ってても同じように動くのか?」
「動くように作ってある。メモリ上の住所というか、場所のことをアドレスと言うんだけど、パソコン側で確保したアドレスを教えてもらったら、そのアドレスを忘れずにメモしておく。メモリを使う時は毎回そのメモを見れば安心。そのメモの事をポインタと呼んでる」
妹「メモ見なくて当てずっぽうでやったら?」
「C++なら絶対にここを使う!と決めてあるプログラムも書ける。ただそこがたまたま空いてたり、知ってるやつが使用中のメモリならいいけど、別の人が使ってるとこだと大変。同じ競技場でサッカーと野球をやるような危険な状態になる。まともに動かないし、最悪パソコンがぶっ壊れる」
妹「そんな恐ろしいこと出来ていいのか……」
「例えばWindows自体を作るような時にはそういう機能も必要なんだよ。自分用に確保された場所で使えば他に影響はないし。でも普通のプログラミング言語では危ないから出来ないようにしてある。ブループリントでも出来ない。あとセキュリティプログラムに阻止されることもある」
妹「ちゃんと阻止してくれ」
「昔よりは事前に阻止されるケースが増えてるよ。色々進歩してるから。その分使えなくなった便利なソフトもあるけどね。そこは安全性を重視するということで」
妹「ポインタがアドレスを書いたメモで……ポインタが参照のことなら……じゃあ実体とはなんなのだ? 画面に出てるキャラクターとかのこと?」
「アクターの場合は結果としてそうなるんだけど、コンピューター目線で考えるとメモリに書き込んであるデータのことを実体という。だから別に画面に出てなくてもいい」
妹「なんかちょっとわかってきたような気がする」
「ついで説明しておくとアドレスというのは先頭から何バイト目というシンプルな情報。整数として表すことが出来るから、つまりポインタは本当は整数型。ただ整数のままだとうっかり足したり引いたりしちゃうから、それが出来ない様に別の型ということにしてある。C++だと特殊な記号とか使わないとその生の数字は表に出てこないし、どうやっても出てこないようにしてある言語の方が多い」
妹「うーん、どのアドレスに必要なものがあるかわかってれば、ポインタ使わなくても操作出来るんじゃない?」
「ポインタがないとアドレスがわからないでしょう」
妹「うん? そうかなあ? まだなんかちょっと引っかかるんだけど…… まあいいか、次だ次いこう。参照をいくらコピーしても実体は増えないんだよね?」
「増えないね」
妹「じゃあさ、そもそも参照をコピーする意味ってなくない? 意味なかったら誰も使わなくない? 参照をコピーすると自動的に実体をコピーするとかでもいいんじゃない?」
「あーそういうことか。なんとなく、何がわかってないのかわかってきた」
妹「ようやくわかってくれたか」
「関数の呼び出し……ブループリントで言うとピンをつないでる線だけど、あれはコピーしてるんだよ」
妹「そうなの?」
「コピーしないと他のノードに情報が伝わらないんで」
妹「別にコピーしなくても見せればよくない? ちらっと」
「見せる……そうか、うーん、人間で例えると、見せたとしても、それを脳が覚えてなかったら意味ないというか。ボケーっと見てただけとか、一瞬だったから覚えられないとか」
妹「いやちゃんとよく見せよう」
「覚えてるって事は、メモに書いてあるアドレスが脳にコピーされたってことなんだよ」
妹「メモはコピーしたんじゃなくて? 脳にコピーしてる? ……脳に???」
「そのへんはコンピューターの仕組みに関わるとこでもあるし、わかりにくいかもしれないけど、基本的にコピーしないと情報伝達は出来ない」
妹「そしたらメモを見せるんじゃなく、渡したら? そしたら覚えなくてもいいよ」
「そこは物体と情報とで違うとこなんだけど、情報はコピー出来ても移動出来ない。というか読み取りと書き込みしか出来ない。情報が入った物…スマートフォンとかを持って歩く事は出来るけど、情報は移動してない。そのスマホの中にある」
妹「うーん、でも移動出来るやつ色々あるよ? 絵を書いてる時も、選択範囲で移動とかよくしてるし」
「そういうのはいったんコピーして、元のデータを削除してるんだよ。見えないけど裏ではそうなってる。削除といっても0を書き込んでるとかそんなのだけど」
妹「じゃあ元のデータを読み取りした瞬間に消せば…」
「同時にやったら多分エラメッセージが出て止まる」
妹「じゃあじゃあ、いったん別の場所に退避してから……」
「それは出来るしけど、その別の場所に退避ってのがつまりコピーだから」
妹「結局コピーから逃れる事はできないのか……コピーって言葉が良くないのかな。どうしてもコピーまではしなくていいような気がするんだな。紙とインクが無駄……」
「コピーって用語があれなら他のでもいいけど、他に適切なのがないなあ。ペーストは貼り付けって訳される事もあるけど、コピーはコピーだし」
妹「うーん、じゃあいいよ。コピーはするということで話を進めてくれ」
「情報を受け渡すには必ず情報はコピーされる。だけど大量のデータ、例えばアクターのデータ全部をノードごとに毎回コピーするのはバカバカしいので、参照渡し、つまりポインタだけコピーすることで伝達してる」
妹「数字とかもそうしなくていいのか?」
「さっきも言ったけど、ポインタが記録してるアドレスって結局数字だから。数字をコピーするのもアドレスをコピーするのもデータ量は変わらない。そして参照渡しだと、アドレスを聞いて、その場所の数字を読み込むという手間が多少あるから。値渡しにした方が速くなる」
妹「うーん、さっきはなんでポインタ使わずにアドレス使ったら駄目なのか引っかかってたけど、あれはコピーしないと駄目ってことを聞いてなかったせいかな」
「アドレスがわかるってことはどこかにそのアドレスをコピーして記録してあるってことだからね。ポインタ無しというのはありえない。ポインタ以外のものに記録してもいいんだけど、その記録がポインタの役割をするんだから、結局ポインタを使うのと同じこと」
妹「兄的にはそういう前提で言ってて、でもわたしはそういう前提で聞いてなかったのだ」
「で、どうですか? わかりそうでしょうか?」
妹「昨日よりはだいぶわかってきた雰囲気がある。でもこれ以上は色々やってみないとわかんないな。あとでまたC++の本借りてきて読んでみる」
「この妹の場合はC++より機械語の本から読んだ方が早いのかもなあ。根本的な仕組みから書いてあるし。入門用のやつはもう捨てちゃったけど……」
妹「捨てるなーーー」