今回は、C++でよく出てくる「構造体(struct)とクラス(class)の違い」について解説していきます。
「structとclassって何が違うの?」
「どっちも似たように見えるけど、使い分ける必要はあるの?」
「結局、初心者はどっちを使えばいいの?」
こんな疑問はありませんか?
C++を学び始めると、struct と class がかなり似た書き方で出てくるので、最初は違いがかなり分かりづらいです。ですが、ここを理解しておくと、データをまとめたい場面としっかり設計したい場面を分けて考えやすくなります。
この記事を読み終えると、あなたはstructとclassの違い・どっちを使うべきか・初心者が迷いやすいポイントをしっかり理解できるようになると思いますので、ぜひ最後まで読んでいただけると嬉しいです。
structとclassの違いとは?
結論から言うと、C++の struct と class は、機能面ではかなり似ています。
実は、どちらもメンバ変数を持てますし、メンバ関数も書けますし、コンストラクタも定義できます。つまり、初心者が思いがちな「structはただの変数の集まりで、classだけが本格機能を持つ」という理解は少し違います。
主な違いは、次の2つです。
structはメンバのデフォルトアクセスが publicclassはメンバのデフォルトアクセスが private
さらに継承を書く時も、struct はデフォルトで public 継承、class はデフォルトで private 継承になります。ただ、初心者の段階ではまずメンバのデフォルトアクセスの違いを押さえれば十分です。
なぜ違いを知る必要がある?
違いを知っておく必要があるのは、コードの意図を伝えやすくなるからです。
たとえば、座標や色のように単純なデータをまとめたいだけなら struct がかなり自然です。一方で、HPを勝手にマイナスにされたくない、外から直接触らせたくない、といったルールを持たせたい設計なら class の方が向いています。
クラスそのものの基本を先に整理したい方は、クラスの記事もあわせて読むと理解しやすいです。
まずはコードで違いを見てみよう
まずは、デフォルトアクセスの違いが一番わかりやすい例を見てみましょう。
▼main.cpp
#include <iostream>
struct PlayerStruct {
int hp = 100;
};
class PlayerClass {
int hp = 100;
};
int main() {
PlayerStruct a;
std::cout << "PlayerStruct.hp: " << a.hp << "\n";
PlayerClass b;
// std::cout << b.hp << "\n"; // これはエラー
return 0;
}実行結果
PlayerStruct.hp: 100
struct では何も書かなくても hp が外から見えますが、class では何も書かないと private 扱いになるので、そのままでは外からアクセスできません。
structでも関数は書ける
ここで初心者がかなり勘違いしやすいのですが、structにも関数は書けます。
▼main.cpp
#include <iostream>
struct Vec2 {
float x;
float y;
void Print() const {
std::cout << "x: " << x << ", y: " << y << "\n";
}
};
int main() {
Vec2 pos = {10.0f, 20.0f};
pos.Print();
return 0;
}実行結果
x: 10, y: 20
このように、struct だからといって「関数を書けない」「簡易版class」というわけではありません。違いはあくまで、デフォルトの見え方のほうが本質です。
どっちを使えばいい?
結論としては、次のように考えるとかなり分かりやすいです。
- struct:座標、色、設定値など、単純なデータのまとまり
- class:状態管理やルールを持たせたい、外から勝手に触らせたくない設計
たとえば、ゲーム制作なら Vec2、Color、Rect のようなものは struct でかなり自然です。一方で、プレイヤーや敵キャラのように「HPは0未満にしない」「ダメージ処理は専用関数を通す」などのルールがあるものは class の方が向いています。
実際、ポインタや参照と組み合わせてオブジェクトを扱う場面では、ポインタの記事の内容ともかなりつながってきます。
実践例
では、struct と class をそれぞれ自然な場面で使った例を見てみましょう。
▼main.cpp
#include <iostream>
struct Vec2 {
float x;
float y;
};
class Player {
public:
Player(int hp, Vec2 pos) : m_hp(hp), m_pos(pos) {}
void TakeDamage(int damage) {
m_hp -= damage;
if (m_hp < 0) {
m_hp = 0;
}
}
void PrintStatus() const {
std::cout << "HP: " << m_hp
<< ", Pos(" << m_pos.x << ", " << m_pos.y << ")\n";
}
private:
int m_hp;
Vec2 m_pos;
};
int main() {
Vec2 startPos = {100.0f, 200.0f};
Player player(100, startPos);
player.PrintStatus();
player.TakeDamage(30);
player.PrintStatus();
return 0;
}実行結果
HP: 100, Pos(100, 200)
HP: 70, Pos(100, 200)
この例では、座標はただのデータなので struct、プレイヤーはダメージ処理やHP管理のルールを持つので class にしています。こうすると、役割の違いがかなり見えやすくなります。
【重要】私が実際にstructとclassで困った体験談
私も自主制作で最初の頃は、とりあえず全部structで書いてしまうことがありました。
最初は書きやすいので問題ないように見えたのですが、敵キャラのHPや状態フラグまで全部publicのまま置いていたので、別の処理から気軽に値を書き換えられてしまい、「どこで値が壊れたのか分からない」状態になったことがあります。
特に、ダメージ処理のはずなのに別の場所で直接 hp = -50 のような代入が起きていて、バグの原因を追うのにかなり時間がかかりました。
そこで、単純な座標や設定値だけを struct にして、状態管理が必要なものは class に分けるようにしたところ、コードがかなり整理されました。これで、「とりあえず全部struct」でも「全部class」でもなく、役割で分けるのが大事だと実感しました。
こういう設計のズレは、コード量が増えるほど気づきにくくなります。変数の変化を追う時は、C++でのデバッグのやり方の記事もかなり参考になります。
structとclass使用時のよくある失敗例と対処法
- structは関数を書けないと思ってしまう
structにもメンバ関数やコンストラクタは書けます。違いは主にデフォルトアクセスです。 - classにしたのにpublicを書き忘れる
classは何も書かないとprivateです。外から使う関数はpublic:の下に書きましょう。 - 全部どちらか一方に統一しようとしてしまう
大事なのは統一よりも役割です。単純データならstruct、隠したい状態やルールがあるならclassと考えると整理しやすいです。
注意点
structとclassは見た目ほど別物ではありません- 違いは「機能の有無」よりも「デフォルトアクセス」と「設計意図」にあります
- 初心者のうちは、まず「データだけならstruct」「管理したいならclass」で考えるとかなり分かりやすいです
また、ヘッダーファイルに分けて書く時は、#includeの””と<>の違いの記事もあわせて読むと、複数ファイル構成が理解しやすくなります。
まとめ
- struct と class は、C++では機能面がかなり似ている
- 大きな違いは、structはデフォルトでpublic、classはデフォルトでprivate という点
- 単純なデータのまとまりには
structが向いている - 状態管理やルールを持たせたいものには
classが向いている - 「どっちが上か」ではなく、役割で使い分けるのが大切
structとclassの違いは、最初は小さく見えるかもしれませんが、設計を進めていくとかなり効いてきます。
「外から自由に触っていいデータなのか、それともルールを守って操作させたいのか」を基準に考えると、かなり判断しやすくなります。
ここまで読んでくださり、ありがとうございました。

