クラス

C言語だけでプログラムを書くことができます。 しかし、C++を混ぜてもコンパイルできます。 特に、クラスを使いたいので、クラスの説明をします。

構造体とクラス

WNDCLASSEX構造体は、次のように定義されています。

typedef struct {
  UINT      cbSize;
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
  LPCTSTR   lpszClassName;
  HICON     hIconSm;
} WNDCLASSEX;

これは、よくあるWindowsプログラムに出てきました。 これを例に使って説明していきます。

解説

構造体の書き方

さて、C++になって、C言語の構造体は大幅に拡張されました。 まず、次のように書くことができます。

struct WNDCLASSEX{
  UINT      cbSize;
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
  LPCTSTR   lpszClassName;
  HICON     hIconSm;
};

変数宣言は次のようにします。

WNDCLASSEX wc;

このため、wc は、WNDCLASSEX型の変数といいます。 WNDCLASSEX構造体の変数ともいいます。

メンバーにアクセスするのはC言語と同じで、ドット"."を使います。

wc.lpszClassName = "win125";

話はそれますが、文字コードが unicode の場合、次のように "L" を付けて書かなければいけません。

wc.lpszClassName = L"win125";

また、TEXT() マクロを使い、次のように書きます。

wc.lpszClassName = TEXT("win125");

さて、C++では struct だけでなく、class と書くこともできます。

class WNDCLASSEX{
  UINT      cbSize;
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
  LPCTSTR   lpszClassName;
  HICON     hIconSm;
};

struct と class をあわせてクラスといいます。 C++ では、構造体とクラスは同じです。 ただ、新しい書き方では class を使うのが一般的です。

"public:" と "private:"

次は、"public:" と "private:" が導入されました。 "private:" を使うと、クラスの外から見えなくなります。 "public:" は、その逆です。 ところで、これを省略して書くと、struct の場合は public、class の場合は private になります。 この点を除いて、struct と class は同じです。

class	WNDCLASSEX{
public:
  UINT      cbSize;
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
private:
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
public:
  LPCTSTR   lpszClassName;
  HICON     hIconSm;
};

"private:" の後のメンバーは、このクラスの外からアクセスできません。 ですから、つぎのように書けばコンパイルエラーとなります。

wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);

メソッド

これでは意味がないように思えますが、 クラスでは、メンバーに関数も入れることができます。 これをメソッドといいます。 では、"BackColor" というメソッドを作ってみます。

class	WNDCLASSEX{
public:
  UINT      cbSize;
  UINT      style;
  WNDPROC   lpfnWndProc;
  int       cbClsExtra;
  int       cbWndExtra;
  HINSTANCE hInstance;
  HICON     hIcon;
  HCURSOR   hCursor;
private:
  HBRUSH    hbrBackground;
  LPCTSTR   lpszMenuName;
public:
  LPCTSTR   lpszClassName;
  HICON     hIconSm;
  
  void BackColor(HBRUSH col){
    hbrBackground = col;
  }
};

メソッドは、普通の関数と同じように書きます。 使うときも、他のメンバーと同じように使います。

wc.BackColor((HBRUSH)(COLOR_BACKGROUND + 1));

これで、hbrBackground の値を変えることができます。

継承

次は、別名です。WNDCLASSEX型を、MyWndClass型として使うときは、継承という機能を使います。 次のように書きます。

// MyWndClass クラス
class MyWndClass : public WNDCLASSEX{
};

MyWndClass クラスは、WNDCLASSEX 構造体と同じメンバーを持ちます。 このとき、WNDCLASSEX をスーパークラスとか、親クラスといいます。 MyWndClass の方は、子クラスといいます。 さらに、子クラスでは、メンバーを追加することができます。

コンストラクタ

次は、コンストラクタです。 変数宣言時に、自動で1度だけ実行してくれます。 必ず、public にして次のように書きます。 クラス名を用いて、関数のように書きます。 引数も付けることができます。

class MyWndClass : public WNDCLASSEX{

public:
	// コンストラクタ
	MyWndClass(LPCTSTR AppName){
		
		// ウィンドウの定義
		cbSize = sizeof(WNDCLASSEX);	// WNDCLASSEXのサイズ
		style = 0;						// 拡張スタイル
		lpfnWndProc = WndProc;			// ウィンドウプロシージャ
		cbClsExtra = 0;					// 追加領域
		cbWndExtra = 0;					// 追加領域
		hInstance = hInst;				// インスタンス
		hIcon = LoadIcon(NULL,IDI_APPLICATION);		// アイコン
		hCursor = LoadCursor(NULL,IDC_ARROW);		// カーソル
		hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);	// 背景ブラシ
		lpszMenuName = NULL;						// メニュー
		lpszClassName = AppName;					// クラス名
		hIconSm = LoadIcon(NULL, IDI_WINLOGO);		// 小さなアイコン
	}
};

ですから、メンバーの初期化に使えます。 上の場合、よくあるWindowsプログラムと同じ値を代入しました。 また、アプリケーション名を引数にしました。

変数の宣言は、次のように書きます。 引数があるので、変な感じがします。 この時点で自動的にコンストラクタを実行するので、よくあるWindowsプログラムと同じ値になります。

MyWndClass wc(TEXT("win125"));

使うときは構造体と同じで、ドット"." を使って、wc.style のように使います。

さて、上のように書く以外に、宣言だけ書いて、中身は外に書くこともできます。 外に書くときは、かならず "MyWndClass::" を付けます。

class MyWndClass : public WNDCLASSEX{

public:
	// コンストラクタ
	MyWndClass(LPCTSTR AppName);
};

//--------------------------------------------------------------------------------------

// コンストラクタ
MyWndClass::MyWndClass(LPCTSTR AppName){

	// ウィンドウの定義
	cbSize = sizeof(WNDCLASSEX);	// WNDCLASSEXのサイズ
	style = 0;						// 拡張スタイル
	lpfnWndProc = WndProc;			// ウィンドウプロシージャ
	cbClsExtra = 0;					// 追加領域
	cbWndExtra = 0;					// 追加領域
	hInstance = hInst;				// インスタンス
	hIcon = LoadIcon(NULL,IDI_APPLICATION);		// アイコン
	hCursor = LoadCursor(NULL,IDC_ARROW);		// カーソル
	hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);	// 背景ブラシ
	lpszMenuName = NULL;						// メニュー
	lpszClassName = AppName;					// クラス名
	hIconSm = LoadIcon(NULL, IDI_WINLOGO);		// 小さなアイコン
}

このように書けば、2つのファイルに分割することができます。 ファイル名は、"MyWndClass.h" と "MyWndClass.cpp"とすればわかり易いです。


[目次] [次]