C++で本格的なプログラムを書き始めると、必ず登場するのがクラスです。
クラスはデータと処理をひとまとめにできる仕組みで、オブジェクト指向プログラミングの中心的な概念です。
本記事では、クラスの基本構造からコンストラクタ、メンバ関数、アクセス指定子、さらに少し応用的な使い方までを、サンプルコードと図解を用いながら丁寧に解説します。
C++のクラスとは何か
クラスの役割とイメージ

クラスとは、「データ」と「そのデータを扱う処理」を1つにまとめた設計図のようなものです。
C言語では構造体でデータだけをまとめていましたが、クラスではそれに加えて関数も一緒に持たせることができます。
たとえばゲームのプレイヤーを表すとき、次のような情報と処理をまとめて持てると便利です。
- プレイヤー名やHPなどのデータ
- ダメージを受ける、回復する、状態を表示するなどの処理
この「プレイヤーの設計図」がクラスであり、その設計図から実体として作られるものがオブジェクトです。
クラスは1つでも、そこから何体分ものプレイヤーオブジェクトを生成できます。
クラスの基本構造
クラス定義の書き方

C++でクラスを定義する基本形は次のようになります。
// クラスの基本的な書き方
class クラス名 {
// アクセス指定子: public, private, protected など
public:
// 外からも使えるメンバ(変数・関数)
private:
// クラスの内部からのみ使えるメンバ
};
クラス定義では、最後の;を忘れやすいので注意が必要です。
クラスは通常、関数の外(グローバルな位置)に書きます。
最もシンプルなクラス例
それでは、位置情報だけを持つシンプルなクラスを定義してみます。
#include <iostream>
using namespace std;
// 2次元座標を表すクラス
class Point {
public:
int x; // x座標
int y; // y座標
};
int main() {
Point p; // Pointクラスのオブジェクトを生成
p.x = 10; // メンバ変数xに代入
p.y = 20; // メンバ変数yに代入
cout << "x = " << p.x << ", y = " << p.y << endl;
return 0;
}
x = 10, y = 20
この例では、クラス定義とオブジェクトの生成、そして.演算子によるメンバ変数へのアクセスという、クラスの最初の一歩を確認できます。
メンバ変数とメンバ関数
データと処理をまとめる

クラスの中には、主に次の2種類の要素を定義します。
- メンバ変数(フィールド) … クラスが持つデータ
- メンバ関数(メソッド) … そのデータを扱う関数
次の例で、両方をまとめて確認してみます。
#include <iostream>
#include <string>
using namespace std;
// プレイヤーを表すクラス
class Player {
public:
// メンバ変数
string name; // プレイヤー名
int hp; // 体力
int level; // レベル
// メンバ関数: ステータスを表示する
void showStatus() {
cout << "名前: " << name
<< ", HP: " << hp
<< ", レベル: " << level << endl;
}
// メンバ関数: ダメージを受ける
void damage(int amount) {
hp -= amount;
if (hp < 0) {
hp = 0;
}
}
};
int main() {
Player p; // Playerオブジェクトの生成
// メンバ変数に値を設定
p.name = "Alice";
p.hp = 100;
p.level = 5;
p.showStatus(); // メンバ関数の呼び出し
p.damage(30); // 30ダメージを受ける
p.showStatus(); // もう一度表示
return 0;
}
名前: Alice, HP: 100, レベル: 5
名前: Alice, HP: 70, レベル: 5
メンバ関数の中からは、同じクラスのメンバ変数nameやhpに、そのままアクセスできます。
クラスの「内側」では、自分が持っているデータを直接操作できるとイメージすると理解しやすいです。
コンストラクタとデストラクタ
コンストラクタで初期化する

クラスには、オブジェクト生成時に自動で呼ばれる特別な関数があります。
これをコンストラクタと呼びます。
初期値を設定したり、必要な準備を行ったりするのに使われます。
#include <iostream>
#include <string>
using namespace std;
class Player {
public:
string name;
int hp;
int level;
// コンストラクタ: デフォルトの初期値を設定
Player() {
name = "NoName";
hp = 100;
level = 1;
}
// 引数つきコンストラクタ: 好きな値で初期化
Player(const string& n, int h, int lv) {
name = n;
hp = h;
level = lv;
}
void showStatus() {
cout << "名前: " << name
<< ", HP: " << hp
<< ", レベル: " << level << endl;
}
};
int main() {
Player p1; // デフォルトコンストラクタ
Player p2("Bob", 150, 10); // 引数つきコンストラクタ
p1.showStatus();
p2.showStatus();
return 0;
}
名前: NoName, HP: 100, レベル: 1
名前: Bob, HP: 150, レベル: 10
コンストラクタはクラス名と同じ名前で書き、戻り値の型は記述しません。
複数定義しておき、引数の違いで使い分けることもできます。
デストラクタの役割
デストラクタは、オブジェクトが破棄されるときに自動で呼ばれる特別な関数です。
外部リソースの解放などに使います。
#include <iostream>
using namespace std;
class Sample {
public:
Sample() {
cout << "コンストラクタ呼び出し" << endl;
}
// デストラクタ: ~クラス名 という名前で定義
~Sample() {
cout << "デストラクタ呼び出し" << endl;
}
};
int main() {
{
Sample s; // このブロック内で生存
} // ブロックを抜けるとsが破棄され、デストラクタが呼ばれる
return 0;
}
コンストラクタ呼び出し
デストラクタ呼び出し
このように、デストラクタは主にメモリ以外のリソース(ファイル、ソケットなど)の後片付けで役立ちます。
アクセス指定子とカプセル化
publicとprivateの違い

クラスの重要な概念にカプセル化があります。
これは、必要のない内部詳細を外から隠し、決められた方法だけで操作させるという考え方です。
C++では、主に次の2つのアクセス指定子を使います。
public… クラスの外部からアクセス可能private… クラスの内部からのみアクセス可能
実践的なクラスでは、データ(メンバ変数)はprivateにして、操作のための関数だけをpublicにすることが多いです。
#include <iostream>
using namespace std;
class Account {
private:
int balance; // 残高は外から直接いじらせない
public:
// コンストラクタ
Account(int initial) {
if (initial < 0) {
initial = 0;
}
balance = initial;
}
// 預け入れ
void deposit(int amount) {
if (amount > 0) {
balance += amount;
}
}
// 引き出し
void withdraw(int amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
}
}
// 残高取得
int getBalance() const {
return balance;
}
};
int main() {
Account acc(1000); // 残高1000円で口座開設
// acc.balance = 500; // コンパイルエラー(privateのため)
acc.deposit(500); // 500円預ける
acc.withdraw(300); // 300円引き出す
cout << "残高: " << acc.getBalance() << " 円" << endl;
return 0;
}
残高: 1200 円
このように「データは隠して、操作だけ公開する」という設計にすると、不正な値が入るのを防ぎ、クラスの使い方も分かりやすくなります。
アクセス指定子のまとめ
クラスでよく使うアクセス指定子を整理します。
| 指定子 | アクセス可能な範囲 | 主な用途 |
|---|---|---|
| public | どこからでもアクセス可能 | インターフェース(外部公開API) |
| private | クラスの内部(と友達宣言された関数・クラス) | 内部実装、守りたいデータや補助処理 |
迷ったら、まずはprivateで定義し、必要になったものだけpublicにするという方針にすると、安全な設計になりやすいです。
thisポインタと参照のイメージ
thisポインタとは

クラスのメンバ関数の中には、自分自身のオブジェクトを指すthisポインタが暗黙に渡されています。
ふだんは意識しなくても動きますが、同名の変数があるときなどに役立ちます。
#include <iostream>
#include <string>
using namespace std;
class Player {
private:
string name;
public:
// 引数名とメンバ変数名が同じ場合、thisを使って区別できる
Player(const string& name) {
this->name = name; // this->name はメンバ変数
}
void show() const {
cout << "プレイヤー名: " << name << endl;
// 実際は this->name と同じ意味
}
};
int main() {
Player p("Carol");
p.show();
return 0;
}
プレイヤー名: Carol
thisは「いま処理しているオブジェクト」へのポインタだと理解しておけば十分です。
慣れてくると、メソッドチェーンのような書き方を実現するために*thisを戻り値にする、といった応用もできます。
実用的なクラスのミニサンプル
簡単な「長方形クラス」を作ってみる

ここまで学んだ内容を組み合わせて、少し実用的なクラスを作ってみます。
長方形のサイズを管理し、面積や周の長さを計算できるクラスです。
#include <iostream>
using namespace std;
// 長方形を表すクラス
class Rectangle {
private:
double width; // 幅
double height; // 高さ
public:
// デフォルトコンストラクタ
Rectangle() {
width = 0.0;
height = 0.0;
}
// 幅と高さを指定するコンストラクタ
Rectangle(double w, double h) {
setSize(w, h); // 共通のチェック処理を使う
}
// 幅と高さをまとめて設定する
void setSize(double w, double h) {
if (w < 0) w = 0;
if (h < 0) h = 0;
width = w;
height = h;
}
// 幅だけ設定
void setWidth(double w) {
if (w < 0) w = 0;
width = w;
}
// 高さだけ設定
void setHeight(double h) {
if (h < 0) h = 0;
height = h;
}
// 幅を取得
double getWidth() const {
return width;
}
// 高さを取得
double getHeight() const {
return height;
}
// 面積を計算
double area() const {
return width * height;
}
// 周の長さを計算
double perimeter() const {
return 2 * (width + height);
}
// 情報を表示
void show() const {
cout << "幅: " << width
<< ", 高さ: " << height
<< ", 面積: " << area()
<< ", 周の長さ: " << perimeter()
<< endl;
}
};
int main() {
Rectangle r1; // 0,0の長方形
Rectangle r2(3.0, 4.0); // 3×4の長方形
r1.setSize(5.0, 2.0); // 後からサイズを設定
r1.show();
r2.show();
// ゲッターを使って値を取り出す
cout << "r2の幅は " << r2.getWidth()
<< ", 高さは " << r2.getHeight() << endl;
return 0;
}
幅: 5, 高さ: 2, 面積: 10, 周の長さ: 14
幅: 3, 高さ: 4, 面積: 12, 周の長さ: 14
r2の幅は 3, 高さは 4
このクラスには次のような特徴があります。
- 幅と高さは
privateで隠し、不正な値(負数)を避ける - 大きさを設定するためのメンバ関数を
publicで提供 - 面積や周の長さといった「長方形らしい動作」をメンバ関数で表現
「データ + データに関する処理 = クラス」というイメージがつかみやすい例になっています。
まとめ
クラスは、C++で大きなプログラムを構築するための基本単位です。
本記事では、クラス定義の書き方、メンバ変数とメンバ関数、コンストラクタとデストラクタ、public/privateによるカプセル化、そしてthisポインタの役割までを一通り見てきました。
まずは「1つの概念を1つのクラスとしてまとめる」ことを意識し、シンプルなクラスから実際に書いてみることで、クラスの使い方に自然と慣れていくはずです。
