‫こんにちは､ ようこそ｡
‫この講義では､ 参照とポインタの代替について学び､ それらがなぜ異なるのか､ なぜそれらを使いたいと思うのかを見ていきたいと思います｡
‫飛び込んで見ましょう｡
‫ポインターと同じように､ よく似た関連概念にリファレンスというものがありますね｡
‫さて､ ポインタもリファレンスも､ 基本的には単なるメモリアドレスである｡
‫どちらも別の変数への参照を保存するもので､ この点では非常によく似ています｡
‫両者の違いは､ 基本的には「配置転換ができるかどうか」に尽きると思います｡
‫基本的に､ 最初に作成した後に､ 別のアドレスを指すことができるのでしょうか？
‫ポインターの場合､ その答えは「イエス」です｡
‫ポインタは､ 正しい型を持つ限り､ いつでも好きなときに新しいメモリアドレス､ 新しいアクター､ 新しいコンポーネントを指すように変更することができます｡
‫一方､ 参照は､ 他の変数を指すように最初に作成したときに一度だけ設定することができ､
‫その後､ 再び変更することはできません｡
‫また､ 変数を再指定すると､ その変数が消えてしまったり､ そのポインタをNULLに設定してしまったりする問題が発生する可能性があるため､
‫これは安全性の高い機能です｡
‫NULLポインターは本質的に何も指していないポインターで､ 何も指していないポインターで何かをしようとすると､
‫実際にエンジンがクラッシュする可能性があります｡
‫ヌルポインタのクラッシュは起こりえません｡
‫では､ さっそく構文を見てみましょう｡
‫そのため､ ポインターを用いてコンテンツにアクセスする場合は､ 特別な構文を使用する必要があります｡
‫この星印をポインタの前に付けるのは､ メモリアドレスではなくポインタの値を取得していることを確認するためで､
‫実際にはメモリアドレスを取得する必要はありません｡
‫その変数が指している変数であるかのように使えばいいのです｡
‫特別な構文を使用する必要はありません｡
‫あとはアドレスへのアクセスですが､ ポインターを使えば自動的にアドレスが手に入ります｡
‫変数を参照で使用する場合は､ 特殊な構文を使用する必要があります｡
‫そのためには､ 演算子のアドレスを使って､ 基本的に元の変数と同じアドレスを取得する必要があります｡
‫そして､ ポインターによるアドレスの変更です｡
‫アドレスを割り当てて､ 演算子のアドレスを使って､ リファレンスでそれを行うことができることを見てきました｡
‫これは許されないので､ 構文もありません｡
‫最後に､ アドレスではなく､ そのアドレスに格納されている実際の値を変更したい場合はどうすればよいのでしょうか｡
‫ポインターを使うには､ また特別な構文が必要になりますね｡
‫その星を付けて､ 何かを割り当てるのです｡
‫つまり､ 実際のアドレスは変更できないので､ 余計な構文は必要なく､ スターアクターポインターを再び参照で代入するわけです｡
‫余計な構文を省いて､ アクター参照イコールにすればいいのです｡
‫アクターは､ ポイントされた場所の値を上書きすることを意味します｡
‫というわけで､ ちょっと理屈っぽい話になってしまいましたが｡
‫実際の例を挙げてみましょう｡
‫つまり､ ゲーム内で受けたダメージを保存しているfloatがあったとして､ その中に現在のダメージが0に設定されていることを保存しているのです｡
‫誰も私たちに損害を与えてはいない｡
‫ここで､ コピーするのではなく､ 関数に渡すために､ この関数への参照を作成したいと思うかもしれませんが､
‫実際には変更しません｡
‫その方法は､ フロートを持っていて､ フロートの後にアンパサンドを入れることです｡
‫そして､ アンパサンドは､ これがfloatへの参照であることを示しています｡
‫これは新しい浮動小数点数そのものではなく､ 浮動小数点数のメモリーを割り当てない｡
‫ポインターメモリーを確保するだけです｡
‫これをdamage refと呼び､ damageと等しい値に設定することができます｡
‫のアドレスを持っていくとか､ そういうことはしなくていいんです｡
‫これは参照､ これは変数と自動的に認識されます｡
‫つまり､ ここでやろうとしていることは､ その変数への参照を設定することです｡
‫そして案の定､ ログを取ると､ まるで普通の浮動小数点数のように印刷することができます｡
‫特別な構文は必要ない｡
‫通常の変数と同じように使うことができるのです｡
‫コンパイル後､ 再生ボタンを押して､ 出力ログを見てみましょう｡ 確かに､
‫ダメージは設定した値であるゼロで出ています｡
‫しかし､ それは必ずしもそのオリジナルの変数のコピーを作っていないことの証明にはならない｡
‫そこで､ 値を変えてみて､ どうなるかチャレンジしてみましょうと言うわけです｡
‫そこで､ ダメージのリファレンスを使って新しい値を設定し､ 元の値をプリントアウトして､
‫リファレンス値の隣に元の値を置いて見てください｡
‫同じなのか､ 違うのか？
‫参照先を変えるだけですが､ オリジナルも変わるのでしょうか？
‫なぜなら､ それは両者が同じ変数であることを意味してしまうからです｡
‫ビデオを一時停止して､ 試してみてください｡
‫なるほど｡
‫お帰りなさい｡
‫では､ これに挑戦してみましょう｡
‫そこで､ 今すぐ参照を変更するために､ damage ref equalsを行います｡
‫そして今回は､ 5つのダメージを与えたと言うつもりです｡ ここでは､ 特別な構文を使う必要がないことに注意してください｡
‫すでに宣言し､ 作成時の最初の行でその参照を設定しているので､ 参照の再指定はしていないのです｡
‫もう二度とできない｡
‫これで､ 値を設定するだけでよくなりましたね｡
‫それで､ 今できることは､ 被害状況を把握すること､ 審判はログに残すことです｡
‫同じ文字列にダメージとパーセントfもつけて､ ここにもダメージを渡してみましょう｡
‫そして､ コンパイルして見てみるのです｡
‫再生ボタンを押し､ 出力ログを見てみると､ 確かにdamage refとdamageが新しい値である5と出力されています｡
‫要するに､ 同じメモリを指す変数が2つあるわけです｡
‫ほとんど､ 同じ変数でも名前が違うと言っていいでしょう｡
‫つまり､ これはポインタと同じようにコピーが必要ないという利点があります｡
‫余計な構文がいらないし､ より安全に使えるからです｡
‫ですから､ 再指定する必要がない限りは､ リファレンスを使用することが一般的に望ましいと言えます｡
‫ここで､ ちょっとわかりにくいので､ ここで使っている記号を簡単におさらいしておきましょう｡
‫C++でよく使われているんですよ｡
‫では､ アンパサンドとスターマークについて､ その意味と文脈を見てみよう｡
‫そこで､ それらを使うとき､ つまり､ 式の中で使うときのコード例をいくつか挙げてみましょう｡
‫変光星の前に星を見ることができるかもしれません｡
‫変数の前にアンパサンドを見かけることがあります｡
‫これはどういうことでしょうか？
‫さて､ 星マークですが､ 変数の前に置くということは､ アンパサンドでアクターポインタの中身を取得する構文になっています｡
‫変数の前や変数への参照の前にアンパサンドを置くと､ その変数のアドレスを取得していると言うことになる｡
‫アクターのアドレスやリファレンスが指すアドレスを取得しているのです｡
‫さて､ 変数の型で使っていたと宣言するとき､ 星とアンパサンドはほとんど逆の意味を持つ｡
‫つまり､ 星印は新しいアクターへのポインターを意味し､ アンパサンドは新しいアクターへの参照を意味します｡
‫つまり､ 式の中で変数と一緒に使うのか､ 変数を宣言する型の中で使うのかで､
‫意味が全く違うということだけは覚えておいてください｡
‫さて､ あまり詳しくは説明しませんが､ さらに付け加えると､ これらは実は他の文脈でもアンパサンドがビットワイズを意味することがあり､
‫星はすでに見たようにUログの文字列で使うことができるのです｡
‫つまり､ この2つの記号の意味が全てではありませんが､ ポインタと参照に言及する重要な意味はほぼ全てです｡
‫素晴らしい内容です｡
‫ここまでで､ ポインタと参照について､ その関係や違い､ そしてなぜそれらを使いたいのかについて学びました｡
‫それでは､ 次回の講義でお会いしましょう｡