ページ 11

クラスの設計

Posted: 2009年8月19日(水) 20:12
by dic
クラスの設計で悩んでいます
というのも弾クラスとプレイヤークラスがあり、
これらのクラスのプライベートメンバ変数に弾の位置、プレイヤーの位置を保持してます
そこで、クラスAとクラスBとにわけて
合計値が3で割り切れたら削除するというプログラムを組みましたが

ソースで表すと以下のようになります

クラスのプライベートな変数へのアクセスを外部に公開してもいいのかと悩んでます

friendクラスを使うか、継承を使うかなど、どのような方法がベストでしょうか?
#include	<iostream>
#include	<vector>
using namespace std;

class	A
{
	vector<int>	m_a;
public:
	vector<int>::iterator	GetBegin() { return m_a.begin(); }
	vector<int>::iterator	GetEnd() { return m_a.end(); }
	vector<int>::iterator	Erase( vector<int>::iterator e ) { return m_a.erase(e); }
	void	Init();
};
void	A::Init() {
	int	i;
	for( i=0; i<10; i++ )
		m_a.push_back(i);
}

class	B
{
	vector<int>	m_b;
public:
	vector<int>::iterator	GetBegin() { return m_b.begin(); }
	vector<int>::iterator	GetEnd() { return m_b.end(); }
	vector<int>::iterator	Erase( vector<int>::iterator e ) { return m_b.erase(e); }
	void	Init();
};
void	B::Init() {
	int	i;
	for( i=0; i<10; i++ )
		m_b.push_back(i);
}

int		main()
{
	A	a;
	B	b;

	a.Init();
	b.Init();

	vector<int>::iterator	pa = a.GetBegin();
	vector<int>::iterator	pb = b.GetBegin();

	while( pa != a.GetEnd() )
	{
		while( pb != b.GetEnd() )
		{
			int	sum;
			sum = *pa + *pb;
			if( sum % 3 == 0 )
			{
				printf( "%d + %d = %d(/3==0)\n", *pa, *pb, sum );
				pa = a.Erase(pa);
				pb = b.Erase(pb);
			}
			else
				pb++;
		}
		pa++;
	}

	printf( "--- A::m_a ---\n" );
	pa = a.GetBegin();
	while( pa != a.GetEnd() ) {
		printf( "%d\n", *pa );
		pa++;
	}
	printf( "--- B::m_b ---\n" );
	pb = b.GetBegin();
	while( pb != b.GetEnd() ) {
		printf( "%d\n", *pb );
		pb++;
	}
	return 0;
}

Re:クラスの設計

Posted: 2009年8月19日(水) 21:04
by array
> クラスのプライベートな変数へのアクセスを外部に公開してもいいのかと悩んでます
> friendクラスを使うか、継承を使うかなど、どのような方法がベストでしょうか?

クラス内ではなく、外部に変数を用意してクラスをインスタンス化(オブジェクト化)する際にクラス内にアドレスを保持して、クラス内ではアドレスを参照して外部の変数の操作をするのが良いと思います。
(C言語の関数内で変数をreturnで返すのではなく、関数を使う際にポインタで引数を取るのと同じ様な考え方です。)

そうすれば、クラスのプライベートな変数へのアクセスを外部に公開しているような矛盾は無くなると思います・・・。

Re:クラスの設計

Posted: 2009年8月20日(木) 04:42
by dic
なるほど そういう方法があったんですね
目から鱗です
ありがとうございました

Re:クラスの設計

Posted: 2009年8月21日(金) 01:06
by Justy
 弾クラス・プレイヤークラスとクラス A・Bの関係とか、
intの値が何なのか、今ひとつよくわからなかったのですが……。

 まぁ、解決しているので1点だけ。

 その二重 whileは危険ではないでしょうか。
 a.Erase(pa)の後、paが終端且つ pbが終端でなかった場合、次の *paで
まずいことになります。

Re:クラスの設計

Posted: 2009年8月24日(月) 20:41
by dic
>Justy さん
なんとな~く、バグが発生するような気もしながらプログラミングしてたんですが、
今回の場合に限り、動いたのでそのままにしておきました

そういう条件の場合、たしかに例外が発生しますね
ご指摘ありがとうございます