あるクラスから違うクラスを利用する方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
derok

あるクラスから違うクラスを利用する方法

#1

投稿記事 by derok » 7年前

あるクラスのメンバー関数が、他のクラスのメンバー関数を利用する方法がよく分かりません。
具体的には、マインスイーパーの様なゲームを作るとき、
一マス一マスの状態を管理するクラスのメンバー関数を、描画クラスが使用する方法です。
継承とは少し違うと思いますし、
包含の場合、インスタンスを持つと、データクラスが持つデータ領域の大きさを変更出来ませんし。
ポインタだと、コントラクタの引数にデータオブジェクトのアドレスを入れる必要があり、
少し変な気がします。
一応、ポインタを包含する方法で、上手く動いているんですが、これでいいんでしょうか?
main.cpp

コード:

#include "DxLib.h"
#include "deta.h"
#include "byouga.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen( DX_SCREEN_BACK );
		deta obj1(10,10);
		byouga obu2(50,50,30,&obj1);
		obu2.load();
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
			obu2.paint();
		}
        DxLib_End();
        return 0;
}
deta.h

コード:

#ifndef DEF_DETA_H
#define DEF_DETA_H

class deta{
	int *masufl;//0, 閉じている 1, 開けている 2, 旗を立てている 3, クエスチョンマーク
	int x,y;
	public:
		deta(int,int);
		int nyuusyu(int,int);
		void henkou(int,int,int);
		~deta();
};

#endif
deta.cpp

コード:

#include "deta.h"
#include "DxLib.h"

deta::deta(int x1, int y1){
	masufl=(int *)malloc(sizeof(int)*x1*y1);
	if(masufl==NULL){return;}
	for(int i=0;i<(x1*y1);i++)*(masufl+i)=0;
	x=x1;y=y1;
}

int deta::nyuusyu(int x1,int y1){
	return *(masufl+x*x1+y1);
}

void deta::henkou(int x1,int y1,int atai){
	*(masufl+x*x1+y1)=atai;
}

deta::~deta(){
	free(masufl);
}
byouga.h

コード:

#ifndef DEF_BYOUGA_H
#define DEF_BYOUGA_H
#include "deta.h"

class byouga{
	int x,y,haba ;
	int masu;
	deta *po1;
public:
	byouga(int,int,int,deta *);
	void load();
	void paint();
};

#endif
byouga.cpp

コード:

#include "byouga.h"
#include "DxLib.h"
#include "deta.h"

byouga::byouga(int x1,int y1,int tate,deta *po){
	x=x1;
	y=y1;
	haba=tate;
	po1=po;
}

void byouga::load(){
	masu=LoadGraph("画像/無題2.jpg");
}

void byouga::paint(){
	for(int i=0;i<10;i++){
		for(int i1=0;i1<10;i1++){
			if(po1->nyuusyu(i,i1)==0){
				DrawExtendGraph((x+i*haba),(y+i1*haba),	(x+i*haba+haba-1),(y+i1*haba+haba-1),masu,TRUE);
			}
		}
	}
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: あるクラスから違うクラスを利用する方法

#2

投稿記事 by softya(ソフト屋) » 7年前

マインスイーパーを管理するクラスが描画メソッドを持てば解決すると思います。
つまり、マインスイーパーと言うオブジェクトを管理するクラスであれば描画を行なっても問題はないと考えるわけです。
描画クラスがマインスイーパーのオブジェクトを持とうとするから無理が出るのでは?

deta→dataだと思いますが一般名称をクラスにつけるのは避けられたほうが良いと思います。
何を担当するクラスかが分かりづらいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

nil
記事: 428
登録日時: 8年前

Re: あるクラスから違うクラスを利用する方法

#3

投稿記事 by nil » 7年前

>少し変な気がします。
特に問題はないように思えます。
まぁ私ならばsoftyaさんの仰っている通りに各クラスごとに描画関数をもたせます。

C++ではmalloc,freeではなくnew,deleteを使用してください。

derok

Re: あるクラスから違うクラスを利用する方法

#4

投稿記事 by derok » 7年前

ご返答ありがとうございます。
マインスイーパーを管理するオブジェクトとはどういうことでしょうか?
このマスには爆弾がある。このマスは既に開いている。といったことを記録するクラスのことでしょうか?
そのマス管理クラス内に描画クラスを入れるということですか?
後、もしそういうことならば、マスを開ける処理、爆弾を配置する処理などはどうするのでしょうか。
このマス管理クラスに全て入れていいのでしょうか?
すいません質問ばっかしまして。何分オブジェクト思考プログラムは初めてなので。
手続き型ならある程度経験あるんですが。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: あるクラスから違うクラスを利用する方法

#5

投稿記事 by softya(ソフト屋) » 7年前

例えば、1マスを管理するクラスを包含するクラスがマインスイーパーを管理するクラスということで良いと思います。
マインスイーパーを管理するクラスがマス管理のクラスにメソッドで変化を命令するという図式で如何でしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

derok

Re: あるクラスから違うクラスを利用する方法

#6

投稿記事 by derok » 7年前

包含の方法がよくわかりません。
一マス一マスを管理するオブジェクトには、
縱何マス、横何マス、という引数が必要だと思います。
インスタンスを包含する方法だとその引数を変更できませんよね?
ポインタ、参照を使う方法だと、そのクラスに代入するアドレスにあるクラスはゲーム開始から終了までが寿命である必要がありますよね?
そうするとそのクラスはメイン関数で定義する必要があると思うのですが、
マインスイーパー程度ならともかくRPGなどといった大きなプログラムでは、
メイン関数がごちゃごちゃになる気がします。
また、ひとつのオブジェクトが一マスだけ管理するようにしても、
動的に割り当てられたクラスのポインタにどうやってアドレスを代入すればいいんでしょうか?
クラス一つ一つの作り方なら分かるのですが、
それらの繋ぎ方がよく分かりません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: あるクラスから違うクラスを利用する方法

#7

投稿記事 by softya(ソフト屋) » 7年前

すいません。また明日答えさせてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 9年前
住所: 北海道札幌市
連絡を取る:

Re: あるクラスから違うクラスを利用する方法

#8

投稿記事 by Dixq (管理人) » 7年前

> 何分オブジェクト思考プログラムは初めてなので。

ということであれば、そもそも「描画クラス」という分け方が変です。
オブジェクト指向というからにはオブジェクト単位でクラスを分けるのが普通です。
例えば「描画する」という行為は「物(オブジェクト)」でしょうか。

クラスを小さく細分化していくと、行為に近いものがクラスとなる場合も出てきますが、まず大きなクラスを作る時は、クラスをものとしてとらえて設計して下さい。

> 手続き型ならある程度経験あるんですが。

そういう方のために、C言語版のソースとC++版のソースを用いて紹介したページがあります。
ゲームプログラミングの館にある「ゲームプログラミング設計」
http://dixq.net/g/index.html#GameDesign
にあるd3節なんかが分かりやすいかと思います。

「プレイヤー」という物には「Update」と「Draw」というメソッドがあります。
プレイヤーをUpdateで更新しつつ、Drawで描画するのです。
ゲームではよくUpdateとDrawを対でクラスに持つ構造を見かけます。
まずはこれに従った設計にしてみてはいかがでしょう。

また、別のクラスから別のクラスのメソッドを呼ぶ時は、呼びたいクラスのインスタンスのアドレスを教えてあげます。
A *a = new A();
B *b = new B(a);
としてやれば、BクラスはAクラスのメンバ関数をコールできるようになります。
しかしそれが頻繁に起こるようなら設計がうまくいっていない可能性があります。

クラス間でやり取りをしたいときはインターフェイスを利用すると安全です。
C++ インターフェイス」でググると情報が出てきます。
ゲームプログラミングの館であれば、
http://dixq.net/g/index.html#Menu
のC++編でインターフェイスを用いた実装方法を紹介しています。

derok

Re: あるクラスから違うクラスを利用する方法

#9

投稿記事 by derok » 7年前

softya(ソフト屋)様、Dixp(管理人)様、涼雅様、
御返答頂き有難う御座いました。
new演算子で作成したオブジェクトならば、関数が終了しても破棄されない事を知りませんでした。
また、一マスを管理するオブジェクトと描画するオブジェクトは別物だと思っていましたが、
よく考えてみれば「描画する」はオブジェクトとは言い難いですよね。
これからもまたお世話になるかも知れませんがその時もよろしくお願いします。

閉鎖

“C言語何でも質問掲示板” へ戻る