C++ 基礎からマスターまで — 第6回
構造体とクラスはいつ使用できますか?
本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。
これまで、変数と関数について調べてみました。 しかし、ゲームを作りながらモンスターのID、名前、体力を変数で一つずつ別々に管理するのは結構面倒だ。
int monsterId = 1;
std::string monsterName = "Slime";
int monsterHealth = 30;
モンスターが100匹ならば変数も増え続ける。 このような場合は、互いに関連するデータをまとめてまとめるために構造体を使用します。
構造体
#include <string>
struct Item
{
int id;
std::string name;
int price;
};
Item sword{1, "Sword", 100};
Item sword{1, "Sword", 100};同様に中括弧でメンバーを順番に入れる方法を集計初期化と呼ぶ。 構造体として特別なメモリの塊になるわけではない。関連する値に名前を付けて束ねたカスタムタイプです。
void PrintItem(const Item& item)
{
std::cout << item.name << '\n';
}
Item MakePotion()
{
return Item{2, "Potion", 50};
}
構造体も関数の引数として渡すことも、値として返すこともできます。std::vector<Item>同じコンテナにも保存できます。
クラス
構造体にデータだけを入れておけば、外部から体力を変な値に変えることもできる。
monster.health = -9999;
いいですね。コンパイルはされるがモンスターの状態は壊れた。 これを防ぐために、データとデータを変更する動作を同じクラスにまとめます。
#include <algorithm>
#include <string>
class Monster
{
public:
Monster(int id, const std::string& name, int health)
: id(id), name(name), health(health)
{
}
void TakeDamage(int damage)
{
health = std::max(0, health - damage);
}
int GetHealth() const
{
return health;
}
const std::string& GetName() const
{
return name;
}
private:
int id;
std::string name;
int health;
};
publicは外部に公開する部分であり、privateはクラス内でのみ使用する部分です。 メンバー変数をプライベートに隠し、公開関数を介して状態を変更することをカプセル化と呼びます。
コンストラクタの後ろ: id(id), name(name), health(health)はコンストラクタ初期化リストです。 オブジェクトが作成された後に値を代入するのではなく、メンバーが生成される瞬間すぐに初期化する。
構造体とクラスはまったく異なるもののように見えますが、C ++では基本的なアクセス指定子が異なるという違いが最も大きい。 structは基本がpublic、classは基本がprivateです。
単に値を結ぶ用途ならばstructが楽で、 状態を保護しながら動作まで縛りたい場合は、クラスがより自然です。