クラスの基本


概要

クラスとはC++言語で最も重要な機能で、変数と関数も持つことが可能なデータ構造です。
クラス内に宣言した変数をメンバ変数、関数をメンバ関数、またはメソッドと呼び、
メンバ関数とメンバ変数をまとめてメンバと呼びます。

クラスと構造体の違い

C言語の構造体とC++のクラスの大きな違いは、クラスはメンバ関数を持てることです。
これによって、構造体のデータを関数に渡して処理を行う方法から
クラス単体で処理を行うことが可能となりました。

ですが、C++言語の構造体とC++言語のクラスでは機能的な差はほぼありません。
構造体もメンバ関数を持つことができるだけではなく、
クラスで扱える機能のほとんどを使用することができます。
C++言語の構造体とクラスの違いは「オープンなデータ構造」か
「クローズなデータ構造」くらいです。

C++のクラスや構造体にはメンバのアクセス範囲の設定が可能ですが、
設定を何もしない場合の構造体のデフォルトはどこからでもアクセスできるのに対して、
クラスのデフォルトは外部からのアクセスができません。

struct Struct
{
	int Value;
};

class Class
{
	int Value;
};

Struct struct_data;
struct_data.Value = 100; // 問題ない

Class class_data;
class_data.Value = 1; 	// エラー

上のコードでは構造体のValueに値を代入することは問題ありませんが、
クラスのValueに値を代入しようとするとエラーとなります。
このようにクラスのメンバは外部からアクセスできないようになっているので、
構造体を「(外部からのアクセスに対して)オープンなデータ構造」
クラスを「(外部からのアクセスに対して)クローズなデータ構造」と考えます。

クラスの定義

クラスの定義は構造体と同じように最初に「class」であることを宣言します。
その後、そのクラスにつける名前を記述し、中括弧({})で囲み、
最後にセミコロン(;)をつけます。
メンバ変数やメンバ関数の宣言は中括弧の中に記述を行います。

// 書式例
class クラス名
{

};

// 具体例
class Employee
{

};

メンバ変数の宣言

メンバ変数の宣言は中括弧の間に宣言を行います。
宣言自体はローカル変数やグローバル変数を宣言と同じで
「型 変数名」で宣言が可能です。

// 書式例
class クラス名
{
	メンバ変数
	メンバ変数
};

// 具体例
// 社員クラス
class Employee
{
	int Number; 		// 社員番号
	char Name[32];		// 名前
	int Salary;		// 給料
	int Department = 0;	// 部署
};

具体例のDepartmentのように宣言と同時に初期化することも可能です。
(C++の古いバージョンによってはエラーになることもあります)

メンバ関数の宣言

メンバ関数の宣言もメンバ変数の宣言と同様に中括弧の間に宣言します。
宣言はプロトタイプ宣言を行い、実際の定義は中括弧の外に行います。
この項目では宣言のみの説明をして、別の項目で定義の説明をします。
※関数の定義をクラス内に行うことができますが、そちらの説明は別の記事で行います。

// 書式例
class クラス名
{
	// メンバ関数(プロトタイプ宣言)
	戻り値の型 関数名(引数);
};

// 具体例
// 社員クラス
class Employee
{
	// メンバ関数
	// 社員情報表示
	void ShowInfo();

	// メンバ変数
	int Number; 		// 社員番号
	char Name[32];		// 名前
	int Salary;		// 給料
	int Department = 0;	// 部署
};

メンバ関数の定義

メンバ関数の定義はクラス定義の外で行います。
関数の定義方法は基本的にユーザー関数を作成する方法と同じですが
クラスに所属していることを明確にするために
関数名の前に「所属しているクラス名::」を設定します。
※クラス名と関数名の間に設定している「::」をスコープ解決演算子といいます。

// 書式例
戻り値の型 所属クラス名::関数名(引数情報)
{
	// 処理内部
}

// 具体例
class Employee
{
	// 社員情報表示
	void ShowInfo();

	// メンバ変数
	int Number; 		// 社員番号
	char Name[32];		// 名前
	int Salary;		// 給料
	int Department = 0;	// 部署
};

// 社員情報表示
void Employee::ShowInfo()
{
	printf("社員番号 = %d\n", Number);
	printf("名前 = %s\n", Name);
	printf("給料 = %d\n", Salary);
}

定義したクラスの使い方

宣言したクラスを使用は以下の流れで行います。

順番 内容
変数宣言をする
メンバを使用する

①.変数宣言をする

まずは他の変数を使用する時と同じようにクラスを変数として宣言します。

// 書式例
クラス名 変数名;

// 具体例
// suzukiという変数として宣言
Employee suzuki;

②.メンバを使用する

メンバを使用する方法は以下のように所属している
クラスのメンバ関数の中でメンバを使っているかどうかで書式が異なります。

// メンバ関数の中
class Employee
{
	// 社員情報表示
	void ShowInfo();

	// メンバ変数
	int Number; 		// 社員番号
	char Name[32];		// 名前
	int Salary;		// 給料
	int Department = 0;	// 部署
};

// 社員情報表示
void Employee::ShowInfo()
{
	printf("社員番号 = %d\n", Number);
	printf("名前 = %s\n", Name);
	printf("給料 = %d\n", Salary);
	printf("部署 = %d\n", Department);
}

// メンバ関数の外
Employee suzuki;
suzuki.Number = 100;

書式が異なる理由

メンバ関数内でクラスに所属するメンバを使用する場合、
同じクラスのメンバであることが分かりますが、
それ以外で使用する場合、どのクラスのメンバ変数なのかを
明確にする必要があるために記述方法が異なります。

メンバ関数の外で使用する方法

クラスのメンバをメンバ関数の外で使用するには構造体のように
メンバの前に「変数名.」をつけて「変数名.メンバ変数」「変数名.メンバ関数」とします。

class Employee
{
public:
	// 初期化
	void Init();
	// 社員情報表示
	void ShowInfo();

	// メンバ変数
	int Number; 		// 社員番号
	char Name[32];		// 名前
	int Salary;		// 給料
	int Department = 0;	// 部署
};

// 社員情報表示
void Employee::ShowInfo()
{
	printf("社員番号 = %d\n", Number);
	printf("名前 = %s\n", Name);
	printf("給料 = %d\n", Salary);
	printf("部署 = %d\n", Department);
}

void main()
{
	// suzukiという変数として宣言
	Employee suzuki;

	// クラス変数.メンバ変数
	suzuki.Number = 1001;
	strcpy_s(suzuki.Name, "山田太郎");
	suzuki.Salary = 220000;

	// クラス変数.メンバ関数
	suzuki.ShowInfo();
}

メンバ関数の中で使用する方法

今までのサンプルコードでメンバ関数内の書式は書いてしまっているので
今更ではありますが、メンバ関数の中で使用する場合は
自分のクラス内で宣言している変数や関数ということが分かっているので、
メンバの名前のみで使用できます。

class Employee
{
public:
	// 初期化
	void Init();
	// 社員情報表示
	void ShowInfo();

	// メンバ変数
	int Number; 		// 社員番号
	char Name[32];		// 名前
	int Salary;		// 給料
	int Department;		// 部署
};

// 初期化
void Employee::Init()
{
	Number = 1001;
	strcpy_s(Name, "山田太郎");
	Salary = 220000;

	ShowInfo();
}

// 社員情報表示
void Employee::ShowInfo()
{
	printf("社員番号 = %d\n", Number);
	printf("名前 = %s\n", Name);
	printf("給料 = %d\n", Salary);
	printf("部署 = %d\n", Department);
}

void main()
{
	Employee suzuki;
	suzuki.Init();
}

クラス変数がポインタの場合

クラスの変数がポインタの場合はメンバへのアクセスは「 . 」ではなく
「 -> 」を使用します。

class Employee
{
public:
	// 初期化
	void Init();
	// 社員情報表示
	void ShowInfo();

	// メンバ変数
	int Number; 		// 社員番号
	char Name[32];		// 名前
	int Salary;		// 給料
	int Department;		// 部署
};

// 初期化
void Employee::Init()
{
	Number = 1001;
	strcpy_s(Name, "山田太郎");
	Salary = 220000;

	ShowInfo();
}

// 社員情報表示
void Employee::ShowInfo()
{
	printf("社員番号 = %d\n", Number);
	printf("名前 = %s\n", Name);
	printf("給料 = %d\n", Salary);
	printf("部署 = %d\n", Department);
}

void main()
{
	Employee suzuki;
	Employee* p = &suzuki;

	suzuki->Init(); // 「 . 」ではなく、「 -> 」
}