オブジェクト指向について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
AliceCoder
記事: 51
登録日時: 7年前

オブジェクト指向について

#1

投稿記事 by AliceCoder » 7年前

C++でゲームを作ろうと思いますが、オブジェクト指向についてよく分からないところがあります。
カプセル化を意識してプログラミングをしようと思いますが、悩んでいることがあります。

MapクラスとPlayerクラスがあるとします。
マップの状態を見て、移動可能ならプレイヤーを移動させる
という処理がしたい場合にどうしたら最適かどうかです。

Playerクラスの移動関数の引数に、Mapクラスのオブジェクトのアドレスを渡す方法を考えましたが
カプセル化っぽくなるとは思うのですがPlayerクラスにMapクラスのヘッダをインクルードしないといけないので大規模になるとエラーの元になりそうなので
悩んでいます。

下記のようにオブジェクトを生成したスコープ内で別々に処理をするという方法とどちらがいいのか悩んでいます。

コード:

Map map;
Player player;
if(map.can_move){
  player.move;
}
説明下手ですいませんが誰か考えをお聞かせください
環境はwindows7 64bit
コンパイラ vc++2010

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: オブジェクト指向について

#2

投稿記事 by h2so5 » 7年前

単純な例ですが、自分だったらこうします。
Player も Map も、仲介するための Position 構造体さえ知っていれば良いわけです。

コード:

struct Position {
    int x, y;  
};
 
class Player {
    public:
        const Position& position() const
        {
            return position_;
        }
    private:
        Position position_;
};
 
class Map {
    public:
        bool canMove(const Position& position) const
        {
            return (position.x > 0);
        }
};
 
int main() {
    Map map;
    Player player;
    if (map.canMove(player.position())) {
        // 何かする   
    }
    return 0;
}

AliceCoder
記事: 51
登録日時: 7年前

Re: オブジェクト指向について

#3

投稿記事 by AliceCoder » 7年前

h2so5さん回答ありがとうございます
なるほど、そういう考え方がありましたか
今思いつきましたが、MapクラスのcanMoveの引数を(int x,int y)にして、
実引数に(player.get_x, player.get_y)とかはどうですかね
これならヘッダをインクルードする必要がなくなると思うのですが

他にもいろいろな回答待っています

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: オブジェクト指向について

#4

投稿記事 by h2so5 » 7年前

AliceCoder さんが書きました: 今思いつきましたが、MapクラスのcanMoveの引数を(int x,int y)にして、
実引数に(player.get_x, player.get_y)とかはどうですかね
これならヘッダをインクルードする必要がなくなると思うのですが
この例の場合はそれでも特に問題はないと思いますが、Positionに当たるクラスがもっと複雑なものだったりすると面倒ですし、
カプセル化という観点からもあまり良くないと思います。
クラスにしてしまえばオペレーターオーバーロードが使えるという利点もありますし。

闇雲にインクルードするのは確かに問題ですが、
Positionクラスが書かれているヘッダが Player や Map のヘッダをインクルードするとは考えにくく、
循環インクルードは発生しないのできちんとインクルードガードすれば危険は無いはずです。

AliceCoder
記事: 51
登録日時: 7年前

Re: オブジェクト指向について

#5

投稿記事 by AliceCoder » 7年前

h2so5さん回答再びありがとうございます

すいません書き間違えました
実引数のとこは、(player.get_x(), player.get_y())でアクセサのつもりでした。

なるほど、確かに複雑になってくると値渡しがめんどうになってきますね
次つくるときは経由用の構造体などを作ってみます

他の人の回答もいまだ受付中です。
明日ぐらいになったら解決にするつもりです

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

Re: オブジェクト指向について

#6

投稿記事 by nil » 7年前

単純にヘッダーでのincludeの数を減らしたいのならば、クラス宣言を使うといいでしょう。

AliceCoder
記事: 51
登録日時: 7年前

Re: オブジェクト指向について

#7

投稿記事 by AliceCoder » 7年前

涼雅さん回答ありがとうございます。
クラス宣言ですか
どこで宣言すればいいんですかね

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

Re: オブジェクト指向について

#8

投稿記事 by nil » 7年前

コード:

//  A.h
#include "B.h"
class A{
private:
	const B& b;

public:
	void f( B* pB );
	/*	このように関数やメンバ変数に"B.h"というヘッダーで定義されている
	*	クラスBの『ポインタ』もしくは『参照』を記述したい場合*/
};

//	↓のように書くことができます
class B;	//	クラス宣言
class A{
private:
	const B& b;

public:
	void f( B* pB );
};
ですが、クラスの実体をメンバや引数に取る場合はincludeが必要ですし、クラスBのメンバ関数をA.hで使用したい時にもまた必要です。

AliceCoder
記事: 51
登録日時: 7年前

Re: オブジェクト指向について

#9

投稿記事 by AliceCoder » 7年前

涼雅さん分かりやすく教えてくださりありがとうございます
こういうやり方もあったんですね
勉強になりました

閉鎖

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