Ccmmutty logo
Commutty IT
0 pv4 min read

【C++】構造体とクラス

https://cdn.magicode.io/media/notebox/blob_4we0d4I

C言語における構造体

構造体はある対象に関する項目を1つにまとめたデータ構造です。 以下のような使い方が出来ます。
#include <stdio.h>

struct Employee {
	int Number;			// 社員番号
	char *Name;			// 名前
	int Salary;			// 給料
	int Years;			// 勤続年数
};

void main(void)
{
	struct Employee emp[2];

	emp[0].Number = 1;
	emp[0].Name = "山田太郎";
	emp[0].Salary = 50;
	emp[0].Years = 5;

	emp[1].Number = 2;
	emp[1].Name = "田中二郎";
	emp[1].Salary = 10;
	emp[1].Years = 1;

	for (int i = 0; i < 2; i++)
	{
		printf("社員番号:%d, 名前:%s, 給料:%d円, 勤続年数:%d年\n", emp[i].Number, emp[i].Name, emp[i].Salary, emp[i].Years);
	}
}
実行結果:
社員番号:1, 名前:山田太郎, 給料:50円, 勤続年数:5年
社員番号:2, 名前:田中二郎, 給料:10円, 勤続年数:1年
また、C言語の構造体には関数を含めることは出来ません。

C++言語における構造体

C++言語では関数を含めることが出来ます。
#include <iostream>
#include <string>

using namespace std;

struct Employee {
	int Number;			// 社員番号
	string Name;		// 名前
	int Salary;			// 給料
	int Years;			// 勤続年数

	void SalaryIncrease()
	{
		Salary *= 1.5;
	};
};

int main()
{
	Employee emp[2];

	emp[0].Number = 1;
	emp[0].Name = "山田太郎";
	emp[0].Salary = 50;
	emp[0].Years = 5;

	emp[1].Number = 2;
	emp[1].Name = "田中二郎";
	emp[1].Salary = 10;
	emp[1].Years = 1;

	for (int i = 0; i < 2; i++)
	{
		cout << "社員番号:" << emp[i].Number << ", 名前:" << emp[i].Name << ", 給料:" << emp[i].Salary << "円, 勤続年数:" << emp[i].Years << endl;
	}

	cout << "昇給!!" << endl;

	emp[0].SalaryIncrease();
	emp[1].SalaryIncrease();

	for (int i = 0; i < 2; i++)
	{
		cout << "社員番号:" << emp[i].Number << ", 名前:" << emp[i].Name << ", 給料:" << emp[i].Salary << "円, 勤続年数:" << emp[i].Years << endl;
	}

	return 0;
}
実行結果:
社員番号:1, 名前:山田太郎, 給料:50円, 勤続年数:5
社員番号:2, 名前:田中二郎, 給料:10円, 勤続年数:1
昇給!!
社員番号:1, 名前:山田太郎, 給料:75円, 勤続年数:5
社員番号:2, 名前:田中二郎, 給料:15円, 勤続年数:1

構造体とクラス

さて、C++言語では構造体に関数を含めることが出来ますが、お気付きでしょうか?
そうです。クラスと同じことが出来るようになっているんです。
もちろん継承などもクラスと同様に出来ます。
そんな構造体とクラスは何が違うのでしょうか?
ところで、クラスのメンバ変数やメンバ関数につけるアクセス指定子ですが、
指定しなかったときはどうなるかご存知でしょうか?
#include <iostream>

using namespace std;

class Calc {
	int Num1;
	int Num2;

	int Add()
	{
		return Num1 + Num2;
	}
};

int main()
{
	Calc calc;
	calc.Num1 = 10;
	calc.Num2 = 20;
	cout << calc.Add() << endl;

	return 0;
}
ビルド結果:
error C2248: 'Calc::Num1': private メンバー (クラス 'Calc' で宣言されている) にアクセスできません。
error C2248: 'Calc::Num2': private メンバー (クラス 'Calc' で宣言されている) にアクセスできません。
error C2248: 'Calc::Add': private メンバー (クラス 'Calc' で宣言されている) にアクセスできません。
上記の通り、クラスのデフォルトアクセス指定子はprivateとなっています。
では、構造体ではどうでしょうか?
#include <iostream>

using namespace std;

struct Calc {
	int Num1;
	int Num2;

	int Add()
	{
		return Num1 + Num2;
	}
};

int main()
{
	Calc calc;
	calc.Num1 = 10;
	calc.Num2 = 20;
	cout << calc.Add() << endl;

	return 0;
}
実行結果:
30
問題なく実行することが出来ました。 構造体でのデフォルトアクセス指定子はpublicであることがわかります。

まとめ

C++言語における構造体とクラスの違いは ・クラス:デフォルトのアクセス指定子がprivate
・構造体:デフォルトのアクセス指定子がpublic
となっていました。
そのため、オブジェクトとして扱う場合はどちらも使っても問題無いことがわかります。
(ゆえに使い分けが難しい…)
過去に話を聞いた人たちの意見だと、 ・そもそもメンバはpublicのものから書くことが多いので、最初の指定を省ける構造体を使う。
・クラスはオブジェクト、構造体はデータの管理用として使い分ける。
と、それぞれの考えを聞くことがありました。 恐らく使い分けについては、それぞれのプロジェクトで文化やコード規約があると思いますので、
その場その場で使い分けて行くと良いと思います。

Discussion

コメントにはログインが必要です。