パソコン活用研究シリコンバレー(C、C++、の活用研究)

クラス

=========================================================================================
C++の真髄とか言われているクラスというものを眺めてみることにします。
==========================================================================================




前回のクラスでは、構造体をそのままクラスにしてみて、ほら、クラスって言っても構造体の延長だよ、
みたいなことを書きましたが、今回はもう少しクラスらしいクラスにしてみたいと思います。

1.クラスにメソッドも実装


前回は変数(メンバ変数)だけのクラスを作りました。
これだと、なんも構造体と違わんやん、というものでしたので、今回は一歩進んで星を表示するstarクラスに
メンバ関数(メソッドとも呼ばれます)を付けてみます。

というわけで、starクラスに星を表示する関数(メンバ関数、あるいはメソッド)としてdraw
星を消す関数(メンバ関数、あるいはメソッド)としてclrを付け加えました。

straj2.cpp

#include <stdlib.h>
#include <dos.h>
#include <time.h>
#include <conio.h>
#define num 30

class star
{
public:
int x;
int y;
int c;
void draw() {gotoxy(x,y); textcolor(c);putch('*');};
void clr() {gotoxy(x,y);putch(' ');};
};


main(){
star st;

clrscr(); /*画面クリア*/
_setcursortype(0);

st.x=20; st.y=10;
st.c=2;
st.draw();
_setcursortype(2);
}


前回は、星の表示はmain関数の中から、putch('*') で表示していましたが、
このProgramでは、starクラスのdrawメソッドを使って表示させています。
starクラスの中に、表示したり消したりする機能を実装したわけです。

構造体にはこのメンバ関数(メソッド)を記述することはできなかったので、やっとクラスらしいクラスに
なりました。



2.メンバー変数をprivateにする


さて、今まではメンバ変数もメンバ関数も全てpublicで宣言していました。
publicは公にするという宣言ですから、publicで宣言されたメンバ変数もメンバ関数もクラスの外から
直接アクセスして値を読み取ったり、変更できたりしたわけです。
上のstarj2.cppでは、クラスの外から(すなわちmain関数のプログラムから)直接st.x, st.y, st.c の値を設定
できていたわけです。

でも、外部のプログラムからメンバ変数を直接いじられちゃうのは、どうもなー、と思いますよね。
えっ、思わない?

例えば、星の座標は画面の表示できる範囲内にしたいですよね。x座標に1000とか設定されると困っちゃう
わけです。
まあ、自分ひとりでプログラムしている分にはいいのかもしれませんが、大きなプロジェクトで複数人で
プログラムを分担したりする時のことを考えると、他のプログラマにいきなり星のx座標は1000みたいに
設定されると、困っちゃうわけです。
なので、x座標、y座標、色の変数はクラスの外からアクセスできないように、privateで宣言してみます。
その代りに、x座標、y座標、色を設定するためのメンバ関数(メソッド)も用意して、メンバ関数で値を設定
させることにします。
そのさい、x座標は0〜78、y座標は0〜19、色は0〜7に限定することとし、この範囲外の値を設定しようとすると、
x座標は1、y座標は1、色は7(白)にしてしまうことにします。
それぞれのメンバ関数は、set_x, set_y, set_c としておきます。

publicの直後にあるstarというクラス名と同じメンバ関数はちょっと特殊なもので、コンストラクタと呼ばれる
ものになります。これは次のstarj4.cppで説明しますので、ここでは省略します。

(実行画面)

赤い星は、
st.set_x(99); st.set_y(9); st.set_c(4); /* test3*/
st.draw();
というコードで描画されています。
st.set_x(99);でx座標は99が指定されていますが、x座標は0〜78の範囲外の値を指定したときは
1にされてしまうので、赤い星のx座標は1になっています。

starj3.cpp

#include <stdlib.h>
#include <dos.h>
#include <time.h>
#include <conio.h>
#define num 30


class star
{
private:
int x;
int y;
int c;

public:
star(int p =1, int q=1, int r=7) {
if (p>78 || p<0) p=1;
if (q>19 || q<0) q=1;
if (r>7 || r<0) r=7;
x=p; y=q; c=r;
};
int getx() { return(x);};
int gety(){return(y);};
int getc(){return(c);};

void set_x(int r) { if (r>=0 && r<=78) x=r;
else x=1; };
void set_y(int r) { if (r>=0 && r<=19) y=r;
else y=1;};
void set_c(int r) { if (r>=0 && r<=7) c=r;
else c=7; };

void draw() {gotoxy(x,y); textcolor(c);putch('*');};
void clr() {gotoxy(x,y);putch(' ');};
void init(){x=1; y=1; c=7;};
};


main(){
star st;


clrscr(); /*画面クリア*/
_setcursortype(0);
st.set_x(20); st.set_y(7); st.set_c(2); /*test1*/
st.draw();

st.set_x(21); st.set_y(8); st.set_c(3); /* test2*/
st.draw();

st.set_x(99); st.set_y(9); st.set_c(4); /* test3*/
st.draw();

_setcursortype(2);
}


3.コンストラクタ

クラスと同じ名前のstar()というメンバ関数はコンストラクタです。
コンストラクタはオブジェクトが新しく生成されるときに最初に自動的に呼び出されます。
下のプログラムでは、
star(int p =1, int q=1, int r=7)
としており、各引数(パラメータ)のデフォルト値をp=1, q=1, r=7 と指定しています。
引数のデフォルト値を決めておくと、オブジェクトの生成時に引数を指定しなかった場合には、
このデフォルト値が使われます。


starj4.cpp

#include <stdlib.h>
#include <dos.h>
#include <time.h>
#include <conio.h>
#define num 30

class star
{
private:
int x;
int y;
int c;

public:
star(int p =1, int q=1, int r=7) {
if (p>78 || p<0) p=1;
if (q>19 || q<0) q=1;
if (r>7 || r<0) r=7;
x=p; y=q; c=r;
};
int getx() { return(x);};
int gety(){return(y);};
int getc(){return(c);};

void set_x(int r) { if (r>=0 && r<=78) x=r;
else x=1; };
void set_y(int r) { if (r>=0 && r<=19) y=r;
else y=1;};
void set_c(int r) { if (r>=0 && r<=7) c=r;
else c=7; };

void draw() {gotoxy(x,y); textcolor(c);putch('*');};
void clr() {gotoxy(x,y);putch(' ');};
void init(){x=1; y=1; c=7;};
};


main(){
star a(5,5,1), b(10), c, *d;


clrscr(); /*画面クリア*/
_setcursortype(0);

a.draw(); /*test1*/
b.draw(); /*test2*/
c.draw(); /*test3*/
a=20; a.draw(); /*test4*/
d= new star(6,6,2); d->draw(); /*test5*/


_setcursortype(2);
}

test1 a.draw() 青い星です。aは引数を3つ指定してオブジェクトを生成しているので、指定した引数が使われています。
test2 b.draw() bは最初の引数だけ指定され、2番目、3番目の引数はないのでデフォルト値が使われました。
test3 c.draw() cには引数の指定がないので、全てデフォルト値が使われています。

test4 a=20; a.draw(); により最初の引数に20が使われ、2番目、3番目の引数にはデフォルト値が使われました。
test5 new star(6,6,2);で動的にオブジェクトを生成。 dはポインタ変数なので、メソッドはd->draw(); のように指定します。




TopPage