さぁ、今回からC++で最も大事な機能、「クラス」についての話になります。先ずは、小難しいことは抜きにしてクラスを使ってみましょう。
では、今回の要点です。
では、いってみましょう。
さて、クラスは第1部第58章でやった構造体によく似ています。ただ、struct ではなく class というのを使います。
さて、クラスは本当に構造体とよく似ています。ということで、先ずは構造体と同じように使ってみましょう。手っ取り早いので、第1部第59章のプログラムの struct を class に変えてみることにします。
| プログラム |
|---|
// Class1.cpp
#include <iostream.h>
#define ELEM(array) (sizeof (array) / sizeof *(array))
class SStudent
{
char szName[16];
int nJapanese;
int nMath;
int nEnglish;
};
void Disp(const SStudent& student)
{
cout << "名前 : " << student.szName << endl
<< " 国語 : " << student.nJapanese << " 点, "
"数学 : " << student.nMath << " 点, "
"英語 : " << student.nEnglish << " 点" << endl;
}
int main()
{
SStudent students[] = {
{ "赤井孝", 73, 98, 86, },
{ "笠井大介", 64, 45, 40, },
{ "吉田叶", 76, 78, 69, },
};
int i;
for(i = 0; i < ELEM(students); i++)
Disp(students[i]);
return 0;
} |
| コンパイルエラー(ちょっと改変) |
Class1.cpp(16) : error C2248: 'szName' : private メンバにアクセスできません。 Class1.cpp(17) : 'nJapanese' : private メンバにアクセスできません。 Class1.cpp(18) : 'nMath' : private メンバにアクセスできません。 Class1.cpp(19) : 'nEnglish' : private メンバにアクセスできません。 Class1.cpp(25) : 'initializing' : 'char [7]' から 'class SStudent' に変換することはできません。 Class1.cpp(25) : 'initializing' : 'const int' から 'class SStudent' に変換することはできません。 Class1.cpp(25) : 'initializing' : 'const int' から 'class SStudent' に変換することはできません。 Class1.cpp(25) : 'initializing' : 'const int' から 'class SStudent' に変換することはできません。 Class1.cpp(25) : 直前のエラーを修復できません; コンパイルを中止します。 |
うわぁ、沢山エラーが出てきました。構造体と似ているなんてウソじゃないか!
と、クラスと構造体は確かに似ていますが、やっぱり構造体とはちょっと違うところがあるのです。メンバにアクセスするためには public: というものを書かなければならないのです。どこに書くかというと、メンバの宣言の前です。
class SStudent
{
public:
char szName[16];
int nJapanese;
int nMath;
int nEnglish;
};
これで無事コンパイルできるようになります。実行結果も同じになります。
このように、public:(公開された)というものを書いて初めて、メンバにアクセスできるようになるのです。
さて、クラスには構造体で話した以上の事ができます。何と、関数もメンバにできるのです。実は構造体でもできるのですが、それはC++だけの話です。C言語ではできません。
関数もメンバにできる、というのはいまいちピンとこないかも知れません。ということで、実際のプログラムを見てみましょう。
| プログラム |
|---|
// Class1b.cpp
#include <iostream.h>
#define ELEM(array) (sizeof (array) / sizeof *(array))
class SStudent
{
public:
char szName[16];
int nJapanese;
int nMath;
int nEnglish;
void Disp();
};
void SStudent::Disp()
{
cout << "名前 : " << szName << endl
<< " 国語 : " << nJapanese << " 点, "
"数学 : " << nMath << " 点, "
"英語 : " << nEnglish << " 点" << endl;
}
int main()
{
SStudent students[] = {
{ "赤井孝", 73, 98, 86, },
{ "笠井大介", 64, 45, 40, },
{ "吉田叶", 76, 78, 69, },
};
int i;
for(i = 0; i < ELEM(students); i++)
students[i].Disp();
return 0;
} |
| 実行結果 |
名前 : 赤井孝 国語 : 73 点, 数学 : 98 点, 英語 : 86 点 名前 : 笠井大介 国語 : 64 点, 数学 : 45 点, 英語 : 40 点 名前 : 吉田叶 国語 : 76 点, 数学 : 78 点, 英語 : 69 点 |
赤い部分が上と違う部分です。先ず、クラスの宣言の中です。
void Disp();
こんなのが入ってますね。どうやら、プロトタイプ宣言のようです。そして、次はその実体の定義らしき部分があります。
void SStudent::Disp()
{
cout << "名前 : " << szName << endl
<< " 国語 : " << nJapanese << " 点, "
"数学 : " << nMath << " 点, "
"英語 : " << nEnglish << " 点" << endl;
}
何やら関数名の前に SStudent:: というのがありますね。:: というのは第1部第68章でやったスコープ解決演算子みたいですね。
で、szName というメンバが、オブジェクトなしに使われています。なのにコンパイルエラーは出ず、きちんとプログラムは動いています。
さて、関数を使っているところではどうでしょうか?
students[i].Disp();
関数 Disp は SStudent のメンバなので、メンバ変数の時と同じように . を使ってメンバを使用しています。文法的にはあまり問題ないですが、この関数を呼ぶとどうなるんでしょうかね?
これらについては、次回にお話しします。どうなっているのか、次回を読む前にちょっと考えてみて下さいね。
今回は、これで終わりです。「あれ? ちょっと早いんでないの?」と思うかもしれませんが、ちょっとここでクラスの文法的な意味を推理してほしいのです。まぁ、推理しなくても次回を見ることはできますが、ちょっと推理してから見てほしいですね。
では、今回の要点です。
それでは、次回まで。
Last update was done on 2000.8.2
この講座の著作権はロベールが保有しています