﻿1
00:00:04,410 --> 00:00:05,370
‫こんにちは､ ようこそ｡

2
00:00:05,370 --> 00:00:10,350
‫この講義では､ アウトパラメータと呼ばれる不思議な現象について学びます｡

3
00:00:10,350 --> 00:00:18,240
‫これは､ C++で値を渡す代わりに､ 関数から値を渡すことが多いパラメータです｡

4
00:00:18,330 --> 00:00:25,620
‫また､ 定数参照と呼ばれるものについて､ この2つの概念がどのように互いに絡み合っているのかを見ていきたいと思います｡

5
00:00:25,650 --> 00:00:27,900
‫潜入して解明しよう｡

6
00:00:28,850 --> 00:00:29,180
‫今すぐ

7
00:00:29,180 --> 00:00:36,980
‫なぜなら､ 技術コンポーネントでこのような浮動小数点数の時間を作成するたびに､

8
00:00:36,980 --> 00:00:49,580
‫元の浮動小数点数のコピーを取って関数に渡しているのです｡

9
00:00:49,580 --> 00:00:56,000
‫そこで､ その代わりに､ 参照を取ってそれを渡すようにするとよいでしょう｡

10
00:00:56,090 --> 00:01:03,020
‫そこで､ print damageという関数をgravityで作ることを想像してみましょう｡

11
00:01:03,020 --> 00:01:09,360
‫そして､ この関数の引数として､ floatのダメージを渡したいのです｡

12
00:01:09,380 --> 00:01:14,780
‫さて､ これはさっきも言ったように､ 渡したもののコピーを作って変数にコピーするものです｡

13
00:01:14,780 --> 00:01:18,980
‫print damage関数内にこのパラメータ変数を作成します｡

14
00:01:19,930 --> 00:01:24,610
‫そして､ 最後にセミコロンで完結させるために､ ここでもvoidの戻り値が必要です｡

15
00:01:24,640 --> 00:01:28,630
‫C++の中に入って､ この話を続けよう｡

16
00:01:28,630 --> 00:01:31,030
‫ここでプリントダメージを作りましょう｡

17
00:01:31,300 --> 00:01:39,490
‫その前にyou grab a classを置き､ セミコロンの代わりに中括弧をつけましょう｡

18
00:01:39,670 --> 00:01:48,340
‫つまり､ damageパラメータ変数にコピーして､ damage equals 5を実行しても､ print

19
00:01:48,340 --> 00:01:53,980
‫damageの中でこの変数を変更するだけなので､ 安全なのです｡

20
00:01:53,980 --> 00:01:55,600
‫自分のものにしました｡

21
00:01:55,600 --> 00:01:58,160
‫うっかり失敗するわけにはいかない｡

22
00:01:58,180 --> 00:02:01,460
‫さて､ もしコピーを取りたくないとしたらどうするか｡

23
00:02:01,480 --> 00:02:04,530
‫私の代案は､ リファレンスを取ることです｡

24
00:02:04,540 --> 00:02:14,500
‫ここでできることは､ print damageに入るfloatの参照を置くことで､ C++ファイルでもそれを更新する必要があります｡

25
00:02:14,650 --> 00:02:20,440
‫そして､ このログメッセージはリファレンスとして使っているのですが､ これを取り出してプリントダメージに入れましょう､

26
00:02:20,440 --> 00:02:22,690
‫ということになるかもしれません｡

27
00:02:22,690 --> 00:02:25,360
‫それで今度はダメージを受け､ それをプリントしているのです｡

28
00:02:25,360 --> 00:02:33,490
‫アウトレットはログステートメントを更新して､ damage is this so damages this damageと表示します｡

29
00:02:33,490 --> 00:02:41,470
‫tickコンポーネントでできることは､ print damageとdamage変数を渡して､ 最後にセミコロンをつければ､

30
00:02:41,470 --> 00:02:49,360
‫今のところdamageの参照を取り除くことができます｡

31
00:02:49,480 --> 00:02:51,040
‫TTICで作成されています｡

32
00:02:51,070 --> 00:03:00,100
‫そのためのメモリがここに作られ､ カチカチと音を立てて､ このプリントダメージ機能に渡しに行くのです｡

33
00:03:00,100 --> 00:03:06,670
‫しかし､ このパラメータは参照なので､ 実際にはこのダメージをコピーしているわけではありません｡

34
00:03:06,670 --> 00:03:18,160
‫そのアドレスを参照に格納することで､ この参照を使用する際に､ 実際に元のメモリにアクセスしていることになるのです｡

35
00:03:18,160 --> 00:03:21,970
‫だから､ これがダメージをプリントするようなコピーは起こっていないのです｡

36
00:03:21,970 --> 00:03:25,270
‫では､ 実際に期待通りの動作をしているか確認してみましょう｡

37
00:03:25,270 --> 00:03:35,500
‫例えばダメージの値を5にして､ リコンパイルして再生ボタンを押したら､ その出力ログを見てみてください｡

38
00:03:35,500 --> 00:03:38,590
‫確かに､ 被害が5件という印刷物を手に入れる｡

39
00:03:38,590 --> 00:03:42,910
‫しかし､ 参照があるため､ その値を更新できることがわかります｡

40
00:03:42,910 --> 00:03:49,990
‫つまり､ この関数の中で､ 「ダメージは2に等しい」というようなことができるわけです｡

41
00:03:50,230 --> 00:03:55,510
‫そして､ 気をつけないと､ 自分でコピーしたと思ったら､ それでいいと思ってしまうかもしれない｡

42
00:03:55,510 --> 00:04:01,510
‫しかし､ 実際にはtickコンポーネントで､ 元の変数を変更しているのです｡

43
00:04:01,520 --> 00:04:09,640
‫ですから､ ここに新しいログを入れて､ オリジナルのダメージ変数を検査し､ パーセントFを入れて､ ここにダメージを渡せば､

44
00:04:09,640 --> 00:04:17,230
‫ライブコーディングしてコンパイルし､ 再生を押して出力ログを見てみましょう｡

45
00:04:17,230 --> 00:04:22,990
‫そして今､ ダメージと元のダメージの両方が修正されているのがわかると思います｡

46
00:04:22,990 --> 00:04:27,490
‫どちらも2という数字に変えられていて､ イマイチなんですよね｡

47
00:04:27,490 --> 00:04:35,770
‫予想外の変数を変えてしまうことで､ 失礼ながら誤って大きなダメージを与えてしまうことがあるんですね｡

48
00:04:35,920 --> 00:04:41,380
‫そして､ ここでもまた､ 過去に見たことのある不変のキーワードの使い方が登場します｡

49
00:04:41,530 --> 00:04:52,570
‫floatのリファレンスの前にconstをくっつけると､ ここで言いたいのは､ これは変更できないリファレンスであるべきだということです｡

50
00:04:52,570 --> 00:04:56,440
‫その上で非接触の機能を呼び出すことはできないし､ 設定もできない｡

51
00:04:56,440 --> 00:05:00,430
‫この変数の内容を変更することは､ いかなる方法でもできません｡

52
00:05:00,430 --> 00:05:04,420
‫使うのは自分だけ､ 読むのも自分だけ､ 中身を見るのも自分だけ｡

53
00:05:04,420 --> 00:05:10,570
‫CPPのグラブに戻って､ Constをパラメータに追加してコンパイルすると､

54
00:05:10,570 --> 00:05:22,090
‫ビルドに失敗して､ damageは定数変数なので代入できないというエラーが表示されます｡

55
00:05:22,090 --> 00:05:25,240
‫だから､ 必要な保護ができるのです｡

56
00:05:25,240 --> 00:05:32,950
‫一般に､ 変数のコピーを取らない効率的な方法で変数を渡す場合は､

57
00:05:32,950 --> 00:05:43,900
‫常にcontactキーワードを使用し､ さらに参照も使用します｡

58
00:05:44,200 --> 00:05:53,380
‫しかし､ 時にはその値を変更するために使用したい場合があります｡ 例えば､ ブール値の戻り値があり､

59
00:05:53,380 --> 00:06:06,610
‫ダメージがあると言いたいかもしれませんが､ 過去にBlueprintで行ったように､ 2番目の戻り値を持ちたいと思うかもしれません｡

60
00:06:06,610 --> 00:06:10,810
‫だから､ 私たちは､ どのようにダメージを受けたのか､ そのダメージとは何なのか､ と言うかもしれません｡

61
00:06:10,810 --> 00:06:19,240
‫この場合､ 単純な非 const 参照､ float 参照を使用することは､ 実際には意味があります｡

62
00:06:19,620 --> 00:06:29,330
‫ダメージは､ 通常､ アウトパラメータと呼ばれるものであることを明確にするために､ アウトダメージと呼ぶことにしています｡

63
00:06:29,340 --> 00:06:31,150
‫物を渡すためのパラメータではありません｡

64
00:06:31,170 --> 00:06:33,520
‫物を渡すためのパラメータです｡

65
00:06:33,540 --> 00:06:38,400
‫さて､ C++のちょっと変なクセで､ 見分けがつかないことがあります｡

66
00:06:38,400 --> 00:06:44,460
‫しかし､ 一般的には､ 参照でありながらconstとしてマークされていないパラメータがあれば､

67
00:06:44,460 --> 00:06:50,890
‫誰かがそれをoutパラメータとして使用することを意図していると考えてよいでしょう｡

68
00:06:50,910 --> 00:06:52,560
‫というわけで､ こんな感じです｡

69
00:06:52,560 --> 00:06:53,820
‫ダメージがあるんです｡

70
00:06:53,820 --> 00:07:01,440
‫そして､ これをCPPで実装するとしたら､ グラバークラスを前に置いて､

71
00:07:01,440 --> 00:07:05,950
‫中括弧をここにつければいいわけです｡

72
00:07:05,970 --> 00:07:12,390
‫印刷ダメージの中で､ コスト基準を設定するため､ 不満がある行をコメントアウトすることにしています｡

73
00:07:12,720 --> 00:07:22,230
‫基本的にここでできることは､ いくつかのコードを書いて､ ダメージがあるかどうかを確認し､ 「はい､ わかりました」とプリントアウトすることです｡

74
00:07:22,230 --> 00:07:25,470
‫アウトのダメージは5に等しい｡

75
00:07:25,470 --> 00:07:29,760
‫その分､ ダメージが大きいので､ 戻ることになりますね｡

76
00:07:29,760 --> 00:07:36,570
‫そうですね､ ある程度ダメージを受けているので､ これをティックコンポーネントのようなところで使って､

77
00:07:36,570 --> 00:07:40,110
‫ダメージを手に入れることができるようになりました｡

78
00:07:40,410 --> 00:07:46,080
‫つまり､ ここではダメージを5つ設定する代わりに､ ダメージがあればそれを取得して表示することにします｡

79
00:07:46,080 --> 00:07:56,700
‫つまり､ 以下のように if has damage と言ってから､ ダメージを代入したい変数を渡します｡

80
00:07:56,700 --> 00:08:05,040
‫ですから､ たとえばdamageと､ ステートメントのボディを用意して､ 表示すべきダメージがある場合のみ､ たとえばprint

81
00:08:05,040 --> 00:08:11,990
‫damageを呼び出せば､ このu logを完全に削除することができるのです｡

82
00:08:12,000 --> 00:08:21,420
‫つまり､ これはconstでない参照をoutパラメータとして使用する方法であり､ 関数から複数の戻り値を取得する方法である｡

83
00:08:21,420 --> 00:08:27,510
‫そして､ 通常､ この関数を呼び出すときには､ 変数を作成しますが､

84
00:08:27,510 --> 00:08:29,820
‫初期値は与えません｡

85
00:08:29,820 --> 00:08:37,050
‫39行目で､ 基本的にfloatのダメージが定義されているので､ 次の行でそれをそのまま渡しています｡

86
00:08:37,050 --> 00:08:41,820
‫そして､ これもoutパラメータを使用していることの証左です｡

87
00:08:42,150 --> 00:08:51,570
‫関数に渡す直前に値を与えていないということは､ その関数が値を入れてくれることを期待しているということです｡

88
00:08:51,570 --> 00:08:55,500
‫そのため､ 最初は見分けがつきにくく､ 少し戸惑うかもしれません｡

89
00:08:55,500 --> 00:08:58,260
‫でも､ この2つはぜひ覚えておいてほしいルールです｡

90
00:08:58,260 --> 00:09:05,910
‫変数が宣言され､ 値が与えられず､ 即座に関数に渡されるのを見たら､ それがアウトパラメータであるかどうか自問してください｡

91
00:09:05,910 --> 00:09:15,600
‫もう一つのルールは､ パラメータに参照があり､ それがconstでない場合､ これはoutパラメータであることを示すヒントとなる可能性があります｡

92
00:09:15,600 --> 00:09:24,060
‫もちろん､ 変数やパラメータにoutという名前がついていれば､ これはoutパラメータであることを意味するものであることは間違いありません｡

93
00:09:24,300 --> 00:09:24,960
‫素晴らしい内容です｡

94
00:09:24,960 --> 00:09:28,890
‫これでスイープができるようになったと思います｡

95
00:09:28,890 --> 00:09:30,990
‫では､ 次の講義でお会いしましょう｡

