10:友達なら当たり前
さて、WinMain関数の中に先ほど作成したCGameObjectを作成し、Initialize()を実行させるわけなのですが、すべてのプログラムで1回きりしか使わない関数をpublic
にするのはあまり意味はなく、派生クラスからもアクセスできてしまうのもなんだか不格好です。かといってprivate
ではアクセスできない。そんなときに便利なのがフレンド関数です。
private
な情報もフレンド関数から直接アクセスできるようになるのです。ためしにCGameObjectの宣言部分をこう変えてみましょう。
#pragma once
#include <tchar.h>
#include <windows.h>
#include <dxerr9.h>
#include <d3d9.h>
#include <d3dx9.h>
#define RELEASE(x) {if(x) x->Release();}
class CGameObject
{
private:
static HWND hWnd;
static HINSTANCE hInstance;
BOOL Initialize(HWND hWnd, HINSTANCE hInstance);
void Uninitialize();
friend int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int);
public:
static const HWND GetHWnd(){ return hWnd; }
static const HINSTANCE GetHInstance(){ return hInstance; }
protected:
static LPDIRECT3D9 pD3D;
static LPDIRECT3DDEVICE9 pD3Ddevice;
static LPD3DXSPRITE pSprite;
};
private
に、WinMain()宣言をfriend
としてクラス内に登録しました。この結果、
class CGameObjectChild : public CGameObject
{
void FooUninitialize()
{
Uninitialize();
}
};
int APIENTRY _tWinMain
(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpszCmdLine, int nCmdShow)
{
/* 省略 */
HWND hWnd = CreateWindow(
wc.lpszClassName,
_T("クラスまみれのゲームプログラミング入門"),
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
NULL, NULL, hInstance, NULL );
CGameObject game;
game.Initialize(hWnd, hInstance);
/* 省略 */
game.Uninitialize();
return 0;
}
private
な情報であろうが、自由にいじくり回すことができ、このように使用できる場所を限定させることで、明確なプログラミングができるようになります。ただし、フレンド宣言を多用すると
private
の意味ないじゃん。てなことになりかねませんので、ご利用は計画的に。
// フレンドクラスのデモプログラム
#include <iostream>
using namespace std;
class Class2; // あらかじめの宣言
class Class1
{
private:
friend Class2; // Class2をお友達にすることを宣言
void Kansu()
{
cout << "privateな関数です" << endl;
}
};
class Class2
{
public:
void Kansu2()
{
Class1 c1;
c1.Kansu(); // Class1のプライベートな関数にアクセス
}
};
void main()
{
Class2 c2;
c2.Kansu2();
}