C++: C++ クラス
最終更新:2026-08-31
これまで、構造体で異なる型の変数をまとめました。
でも、現実世界のデータにはプロパティ(名前、年齢)だけでなく、振る舞い(紹介する、勉強する)もあります。
クラスはデータを「カプセル化」 —— プロパティと振る舞いをまとめて管理。
1. クラスとは?
(1) 1.1 クラスの概念
| 概念 | プログラムでの意味 |
|---|---|
| 設計図(型) | クラス(テンプレート) |
| 設計図から作った実体 | オブジェクト(クラスのインスタンス) |
クラス vs オブジェクト:
- クラスはテンプレート(「何ができるか」を定義、振る舞いを指定)
- オブジェクトは実体(テンプレートから作った —— 「実際に存在する」)
(2) 1.2 なぜクラスが必要?
クラスを使わない場合(構造体、振る舞いなし):
CPP
#include <iostream>
#include <string>
struct Student {
std::string name;
int age;
double score;
};
int main() {
Student s1 = {"Alice", 20, 92.5};
// ❌ 「自己紹介」は関数として別に書く(「振る舞い」が分離)
return 0;
}
クラスを使う場合(カプセル化):
CPP
#include <iostream>
#include <string>
class Student {
public:
std::string name;
int age;
double score;
void introduce() {
std::cout << "私は" << name << "、" << age << "歳です。" << std::endl;
}
};
int main() {
Student s1;
s1.name = "Alice";
s1.age = 20;
s1.introduce(); // ✅ 「自己紹介」はメンバー関数
return 0;
}
2. クラスの定義
(1) 2.1 基本的な構文
CPP
class クラス名 {
public:
// メンバー(変数・関数)
};
💡 ヒント: クラス定義の最後にはセミコロンが必要!(構造体と同じ)
▶ サンプル 1:Studentクラスの定義(難易度 ⭐)
CPP
#include <iostream>
#include <string>
class Student {
public:
// メンバー変数(プロパティ)
std::string name;
int age;
double score;
// メンバー関数(振る舞い)
void introduce() {
std::cout << "私は" << name << "、" << age << "歳です。" << std::endl;
}
void study() {
std::cout << name << "は勉強中..." << std::endl;
}
};
int main() {
Student s1;
s1.name = "Alice";
s1.age = 20;
s1.score = 92.5;
s1.introduce();
s1.study();
return 0;
}
出力:
TEXT 📖 参照専用私はAlice、20歳です。 Aliceは勉強中...
3. アクセス制御
C++のクラスには3つのアクセスレベル:public(公開)、private(非公開)、protected(継承先のみ)。
(1) 3.1 public vs private
| アクセス | クラス外からアクセス? | 主な用途 |
|---|---|---|
| public | ✅ 可能 | インターフェース(外部API) |
| private | ❌ 不可 | 実装詳細(隠すべきデータ) |
例:
CPP
#include <iostream>
#include <string>
class Student {
private:
std::string name; // 外部から直接アクセス不可
int age;
public:
// setter と getter
void setName(const std::string& n) {
name = n;
}
std::string getName() {
return name;
}
};
int main() {
Student s1;
// s1.name = "Alice"; // ❌ エラー:nameは非公開
s1.setName("Alice"); // ✅ 公開メソッド経由
std::cout << s1.getName() << std::endl;
return 0;
}
💡 カプセル化のメリット:
private で隠し、public メソッドの setter/getter で制御 —— 将来の変更(バリデーションなど)が楽。
4. コンストラクタ
(1) 4.1 コンストラクタとは?
コンストラクタはクラスの特別なメンバー関数 —— オブジェクト作成時に自動的に呼ばれる。
| 特徴 | 説明 |
|---|---|
| 関数名 | クラス名と同じ |
| 戻り値 | なし(void も書かない) |
| 呼び出しタイミング | オブジェクト作成時 |
▶ サンプル 2:コンストラクタの定義(難易度 ⭐⭐)
CPP
#include <iostream>
#include <string>
class Student {
private:
std::string name;
int age;
public:
// コンストラクタ
Student(const std::string& n, int a) {
name = n;
age = a;
std::cout << "学生作成:" << name << std::endl;
}
void introduce() {
std::cout << "私は" << name << "、" << age << "歳です。" << std::endl;
}
};
int main() {
Student s1("Alice", 20); // ✅ コンストラクタ呼び出し
s1.introduce();
return 0;
}
出力:
TEXT 📖 参照専用学生作成:Alice 私はAlice、20歳です。
5. デストラクタ
(1) 5.1 デストラクタとは?
デストラクタはクラスの特別なメンバー関数 —— オブジェクト破棄時に自動的に呼ばれる(関数終了時、delete など)。
| 特徴 | 説明 |
|---|---|
| 関数名 | ~クラス名 |
| 戻り値 | なし(void も書かない) |
| 引数 | なし |
| 呼び出しタイミング | オブジェクト破棄時 |
▶ サンプル 3:デストラクタの定義(難易度 ⭐⭐)
CPP
#include <iostream>
#include <string>
class Student {
private:
std::string name;
public:
// コンストラクタ
Student(const std::string& n) {
name = n;
std::cout << "作成:" << name << std::endl;
}
// デストラクタ
~Student() {
std::cout << "破棄:" << name << std::endl;
}
};
int main() {
Student s1("Alice"); // コンストラクタ呼び出し
// main終了時、s1が破棄され、デストラクタが呼ばれる
return 0;
}
出力:
TEXT 📖 参照専用作成:Alice 破棄:Alice
💡 使い道: デストラクタはクリーンアップ処理(ファイルを閉じる、動的メモリを解放)に使う。
6. this ポインタ
(1) 6.1 this ポインタとは?
this は現在のオブジェクトへのポインタ —— メンバー関数内で、this は呼び出し元オブジェクトを指す。
▶ サンプル 4:this で同名パラメータを区別(難易度 ⭐⭐)
CPP
#include <iostream>
#include <string>
class Student {
private:
std::string name;
public:
void setName(const std::string& name) { // ⚠️ パラメータ名とメンバー変数名が同じ
this->name = name; // ✅ this-> でメンバー変数を明示
}
std::string getName() {
return this->name; // ✅ this->(省略可能)
}
};
int main() {
Student s1;
s1.setName("Alice");
std::cout << s1.getName() << std::endl;
return 0;
}
💡 ヒント: パラメータ名とメンバー変数名が同じ場合、
this-> で区別(別の名前にする方が簡潔)。
7. 実践例:銀行口座クラス
▶ サンプル 5:BankAccountクラス(難易度 ⭐⭐⭐)
CPP
📖 参照専用
#include <iostream>
#include <string>
#include <iomanip>
class BankAccount {
private:
std::string owner;
double balance;
public:
// コンストラクタ
BankAccount(const std::string& o, double initialBalance) {
owner = o;
if (initialBalance >= 0) {
balance = initialBalance;
} else {
balance = 0.0;
std::cout << "⚠️ 初期残高が不正。0に設定" << std::endl;
}
}
// 入金
void deposit(double amount) {
if (amount > 0) {
balance += amount;
std::cout << "入金完了!+" << amount << std::endl;
} else {
std::cout << "⚠️ 入金額は0より大きく" << std::endl;
}
}
// 出金
void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
std::cout << "出金完了!-" << amount << std::endl;
} else if (amount <= 0) {
std::cout << "⚠️ 出金額は0より大きく" << std::endl;
} else {
std::cout << "⚠️ 残高不足" << std::endl;
}
}
// 残高照会
void queryBalance() {
std::cout << std::fixed << std::setprecision(2);
std::cout << "残高:" << balance << "円" << std::endl;
}
};
int main() {
BankAccount account("MOTO", 1000.0);
account.queryBalance();
account.deposit(500.0);
account.queryBalance();
account.withdraw(200.0);
account.queryBalance();
account.withdraw(2000.0); // 残高不足
return 0;
}
出力例:
TEXT 📖 参照専用残高:1000.00円 入金完了!+500 残高:1500.00円 出金完了!-200 残高:1300.00円 ⚠️ 残高不足
❓ よくある質問
Q クラスと構造体の違いは?
A 本質的な違いは「デフォルトのアクセスレベル」:
classはデフォルトでprivatestructはデフォルトでpublic
それ以外は、struct もメンバー関数、コンストラクタを持てます。
推奨:
Q コンストラクタを書かないとどうなる?
A コンパイラがデフォルトコンストラクタを生成(何もしない、メンバーは未初期化)。
ただし引数付きコンストラクタを書く
📖 まとめ
- クラスはテンプレート、オブジェクトはテンプレートから作った実体
- クラスのアクセスレベル:
public(公開)、private(非公開)、protected(継承先のみ) - コンストラクタ:オブジェクト作成時に呼ばれる、初期化に使う
- デストラクタ:オブジェクト破棄時に呼ばれる、クリーンアップに使う
thisポインタは現在のオブジェクトを指す
📝 練習問題
-
初級(難易度 ⭐):
Bookクラスを定義し、タイトル、著者、価格のメンバーを持たせてください。- 各メンバーの setter と getter を書く
mainでBookオブジェクトを作成して出力
-
中級(難易度 ⭐⭐):
Rectangleクラスを定義し、幅と高さのメンバーを持たせてください。- コンストラクタ(幅と高さを初期化)
double getArea()とdouble getPerimeter()メンバー関数mainでテスト
-
上級(難易度 ⭐⭐⭐):
Dateクラスを定義し、年、月、日のメンバーを持たせてください。- コンストラクタ(年月日を初期化)
bool isValid()メンバー関数(日付の妥当性チェック)void print()メンバー関数(出力、例:2024-02-29)mainでテスト
8. 🚀 次のステップ
クラスとオブジェクトの基本を理解したら、次は コンストラクタ応用(レッスン29) —— デフォルトコンストラクタ、コピーコンストラクタ、ムーブセマンティクス(C++11以降)!