はじめてのC++ 【44日目】

# はじめに
一旦まとめようと思う
## ブロック崩し
ブロック崩しを実際に作るにあたって新たに得られた知識をまとめておこうと思う。
### オブジェクト指向
オブジェクト指向の設計は、上手く作れていないと感じている。しかし、どのようなものがオブジェクト指向なのか薄っすらと理解できた。クラスのカプセル化や再利用可能な設計などの考え方があるとわかった。オブジェクト指向の本格的な取り組みは、ロベールを終わらしてからやろうと思っている。
### クラスのメンバ関数のconstの位置
メンバ関数に `const` を付ける場合は、位置に注意しなければならない。

```cpp
class hoge {
public:
  int x = 10;
  int y = 5;
  int z = 1;

  int getX() 
  {
     return x;
  }
  
  //getY()は、関数定義の前にconstをつけている。
　//この場合は、呼び出したときに帰ってくるint型がconstの値になる。
  //この場合だと、 const int y　の値を得ることができる。
  const int getY() 
  {
     y = y + 1; //コンパイルは通る。問題なし。
     return y;
  }

  //getZ()は、関数定義の後ろにconstをつけている。
  //constが後ろについている場合は、この関数内ではメンバ変数の値を書き換えることはできない。
  int getZ() const 
  {
     //z = z + 1; <- コンパイルエラー
     return z;
  }

};
```
### オブジェクト操作用ポインタ
インスタンスを作り、そのインスタンスをポインタに格納する。それから、そのポインタを使って当たり判定などを付け加える。

```cpp:CreateFactory.h
/*********************************
インスタンスを生成して、ポインタ渡しをする関数
*********************************/

#ifndef CREATE_FACTORY_H
#define CREATE_FACTORY_H

#include "Ball.h"
#include "Box.h"
#include "Bar.h"
#include <array>

class CreateFactory {
public:
  Bar M_bar;
  Ball M_ball;
  std::array<Box, 102> M_Box_List;//ブロックの数が102個用意した。

  Bar* getBar();
  Ball* getBall();
  Box* getBox(int index);
};

#endif
```
```cpp:CreateFactory.cpp
#include "CreateFactory.h"

Bar* CreateFactory::getBar() {
  return &M_bar;
}

Ball* CreateFactory::getBall()  {
  return &M_ball;
}

Box* CreateFactory::getBox(int index)  {
  return &M_Box_List[index];
}
```
いま気づいたが、 

```cpp:
Bar* CreateFactory::getBar() {
  return &M_bar;
}
```
この関数を使うとアドレスが帰ってくる。このアドレスを入れる時にスマートポインタを使うのではと思った。スマートポインタについては、 `new / (delete) ` をしなくていい便利なモノとしか認識しておらず、どのように使うのかイマイチ理解していなかったことが発覚。
```cpp:
std::unique_ptr<Bar> ptr(new Bar);
```
これで、インスタンスとポインタを同時生成できるのかな。また明日試してみる。

### staticの危険性
インスタンス作らないといけないのめんどくせぇーと思っていたら、 ` static `　という超便利なものがあった。 `static`　を付けると、インスタンスを作らなくてもどこでも使える関数になる。実際、 ` Collision.h `の16行目あたりに `static関数` を作ってみたが、かなり危険な匂いがしていた。
[staticおじさんにならないために](https://qiita.com/ue_knnk/items/fa84b8bc30ba319e5744) 
この記事に、 `static` の危険性が書いてあったのでここにメモっとく。

### デバッグメッセージの重要性
当たり判定とか機能しているかどうかを確かめるために、デバックメッセージは必須アイテムだと感じた。

```cpp:Collosion.cpp

  if (ball_x > box_x - width && ball_x < box_x + width)
  {
      if (ball_y > box_y - height && ball_y < box_y + height)
      {
          std::cout << "[Collision] Box-Ball Hit" << std::endl; //重要
          return true;
      }
  }
  return false;
}
```
このように、クラス名とどのような行動をとったときのメッセージなのかを出力するようにしておくと便利になる。そういえば、前にデバックメッセージは `std::cerr` を使うみたいなこと書いてたような気がする。また見返しておこう。

### 同じインスタンスをたくさん作る方法
```cpp:CreateFactory.h
std::array<Box, 102> M_Box_List;
```
固定長配列ならば、 `std::array` を使い生成できる。
それぞれの位置の決め方は、

```cpp:Game.cpp
  for(int i = 0; i < 102; i++)//ブロックのいちを計算している
  {
    Mp_Box_List[i] = mFactory.getBox(i);
    Mp_Box_List[i]->setPosition(5 + 60 * (i % 17), 5 + 60 * (i / 17));
  }
```
このように書くことができる。

### クラスの前方宣言
ヘッダファイルをインクルードしなくても、プロトタイプ宣言でポインタ型を宣言するならクラスの前方宣言で代用できる。

```cpp:Collosion.h
#ifndef COLLISION_H
#define COLLISION_H
//クラスの前方宣言
//関数にポインタだけの場合は、とりあえずこのようなクラスがありますよ！
//、という説明を書いておく。
//※ただし、クラスを実体化させるならそのクラスのヘッダファイルをインクルードしなければならない
//あくまでも、ポインタを使った関数のときのみ使える。
class Bar;
class Box;
class Ball;

class Collision {


public:
  static bool ball_bar_col(Bar* bar, Ball* ball);
  static bool ball_box_col(Box* box, Ball* ball);


};

#endif
```
# 終わりに
ロベールやろうと思ったけど、おもったより時間かかったのでできなかった。
とりあえず今日は寝よう。
おやすみなさい。