キーワード辞典
かなり乱暴なクラスの話(1)

登録日 13/05/28   更新日 13/06/01


この辺って、 言語処理系によってもかなり違って来るので、 物凄くざっくりと。

クラス

オブジェクト指向なプログラミングにおいて、 関連性の有るひとまとめのデータと、 それらのデータを扱うのに適切な手続きとをまとめたもの。

例えば、 右へずらすことによって開くことが出来る扉を、 押しても引いても左へずらしても開くことは出来ない。 その扉は、開ける時は右へずらし、閉じる時は左へずらすという 適切な動作をおこなってのみ、機能する。 同様に、例えば、 番号、氏名、3教科の得点、というひとまとまりのデータが有る場合、 3教科の得点を全て加算すれば合計になるが、 3教科の得点を全て掛け合わせてもその結果には意味は無い(多分)。 手続き指向のプログラミングでは、 データと手続きとが別々に扱われるため、 どのデータが何処でどの様に処理されているのか、の見通しが悪くなり、 時として、前述の「3教科の掛け算」の様なミスが起こり易くなる。 手続き指向のプログラムをオブジェクト指向にしたからと言って、 実行結果が変わる訳ではないが、 プログラムのデータの扱いの判り易さは良くなる。

C言語の構造体は、関連性のあるデータを ひとまとめに扱える様にしたものであるが、 C++のクラスは、それをさらに発展させ、 そのデータを扱うのに適切な手続きも一緒に書ける様にしたものである。 「発展させ」がミソで、 言語処理系やバージョンによって、状況はかなり違う。

元々、C++は手続き指向のCにオブジェクト指向の要素その他を加味したものなので、 オブジェクト指向に対する強制度(?)は弱いが、 Javaは最初からオブジェクト指向を意識しているため、 オブジェクト指向に対する強制度は強かったりする。 C++はメモリの中を把握出来ていると色々と突っ込んだ事が出来るがややこしく、 Javaはポインタが無いなどとっつきやすいがコンピュータ内部が把握し難い、など、 まぁ、この辺は、好き好きなんでしょうか。

C++のクラスのメンバ関数やメンバ変数は、 クラスの外から参照出来るPublicと、 クラスの中だけで作業に使うPrivateとを、明記して扱い分ける事が出来る。 そのことで、手続きの過程での クラスの内部だけの局所的な手続きや変数を気にする必要が無くなる。
明記しない場合は、 そのクラスの中だけのPrivateなものとして扱われる。

C++による、とある2年の実力テスト成績表の例。
手抜きだ、というのは、自覚しております。雰囲気だけ。
敢えてインラインで書いているので警告が出る場合があります。
理系クラスは3教科の受験、文系クラスは2教科の受験で、 それぞれの合計得点を求める。 21Hは理系クラス、22Hと23Hは文系クラス、という設定。 面倒なのでここではしていないが、傾斜配分など、色々出来る。

プログラムの最後で、ichiranという関数を呼び出しているのだが、 呼び出すクラス(Rikei, Bunkei)によって、処理が違っている。 つまり、理系だから、文系だから、という差異を、 此処では意識しなくとも良い様になっている。

// RynClass.cpp		2013.05.28

#include <iostream>
#include <iomanip>
using namespace std;

class Rikei{
    private:
	int   number;
	char* name;
	int   seiseki[3];
    public:
	void ichiran(Rikei* p)
	{
		int i=0;
		int j,k;
		while((p+i)->number < 9999){
			cout << setw(4) << (p+i)->number << " ";
			cout << setw(8) << (p+i)->name;
			k=0;
			for(j=0;j<3;j++){
				cout << setw(4) << (p+i)->seiseki[j];
				k+=(p+i)->seiseki[j];
			}
			cout << setw(6) << k << endl;
			i++;
		}
		cout << endl;
	}
};

class Bunkei{
    private:
	int   number;
	char* name;
	int   seiseki[2];
    public:
	void ichiran(Bunkei* p)
	{
		int i=0;
		int j,k;
		while((p+i)->number < 9999){
			cout << setw(4) << (p+i)->number << " ";
			cout << setw(8) << (p+i)->name;
			k=0;
			for(j=0;j<2;j++){
				cout << setw(4) << (p+i)->seiseki[j];
				k+=(p+i)->seiseki[j];
			}
			cout << setw(10) << k << endl;
			i++;
		}
		cout << endl;
	}
};

void main()
{
	Rikei home21[]=
		{{2101,"atou", 90,90,90},{2102,"katou",100,100,100},
		 {2103,"satou",98,98,98},{9999,"",0,0,0}};

	Bunkei home22[]=
		{{2201,"udou" ,100,95},{2202,"kudou",85,85},
		 {2203,"sudou", 85,85},{9999,"",0,0}};

	Bunkei home23[]=
		{{2301,"endou" ,100,100},{2302,"sendou",85,85},
		 {2303,"tendou", 75, 85},{9999,"",0,0}};

	home21->ichiran(home21);
	home22->ichiran(home22);
	home23->ichiran(home23);
}

実行結果






[ 赤い玉の画像 ] 「キーワード辞典」の目次へ

[ 黒板消しとチョーク受けの画像 ]