ページ 1 / 1
複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 01:14
by 門番
数年振りにこの掲示板に来ました
今も変わらず活発なようで安心いたしました
さて、本題に入ります
私は今RPG風ゲームを作ろうと思い
新・C言語 ~ゲームプログラミングの館~ 様のプログラムを元に
プログラムを組んでおります
RPGで、更に使う言語がC++なのだから(オブジェクト指向らしく?)キャラクターや場面を分けて作ろうと思い、
それぞれクラス分けして作っていたのですが、ここで問題が発生しました
とりあえず簡単なクラス関係を書きます(画像があげられないのとプログラムでは煩雑になるので)
--------------------------------------------------------------------------------
BaseScene(基底)
↑ ↑
Scene1 Scene2(派生)
↑ ↑
Scene1-1,1-2... Scene2-1,2-2...(派生の派生)
------------------------------------------------------------------------------
Character(上記のクラスと継承関係なし基底2)
↑ ↑
敵1... 味方1...(派生2)
↑ ↑
敵まとめ 味方まとめ(派生の派生2)
--------------------------------------------------------------------------------
ここで、Characterクラスにある関数を派生の派生クラスで参照して
Characterクラスにある変数をその関数で変えたいと思い(実際に変わるのは派生2の変数ですが)
BaseScene辺りで味方まとめクラスのオブジェクトを作ろうと思いました
しかしながら、オブジェクトを生成しても自分の思う通りには動きませんでした
その原因として、派生クラス、派生の派生クラスをnewして生成していることにより
それぞれ「別の味方まとめクラス」を参照しているということでした
自分が行いたいのは「一つの味方まとめクラス」から参照することです
要するに(?)、同じ場所にある味方まとめクラスから参照を行いたい、ということです
ポインタの活用等も考えましたが、整理ができず、ここに質問させていただきました
なおC++やオブジェクト指向言語の経験はほとんどありません・・・(Cなら数年間やりましたが・・・
設計の段階からやり直した方がよいのか、今の状態で解決策があるのか、
策があるならばどのようにしていけばよいのかを知りたいです
長くなってしまいましたがよろしくお願いします
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 06:23
by h2so5
そもそもまとめクラスって何なのでしょうか。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 07:46
by 門番
>>h2so5さん
まとめクラスというのは
味方1、味方2...(派生2)のクラスを
Caracter型の1つの配列にして格納してあるクラスです
(この配列にfor文を使って簡単に処理できるように
という意図をもって作りました)
他にも全滅判定でも用いるつもりです
まとめというよりは、
パーティーと言った方が伝わりやすいでしょうか…
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 10:03
by softya(ソフト屋)
継承は論理構造を引き継ぐだけでデータを引き継ぐものではありません。
クラス(論理構造の定義)とインスタンス(データを持つ実体)の違いを意識する必要があります。
なので根本的な設計から勘違いされているのでは無いかと思います。
共通の情報を持つクラスは別に作成されるべきですので、見なおしてプログラムの利用できる分だけを残して利用するほうが良いと私は思います。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 16:50
by 門番
>>softyaさん
共通の情報を持つクラス(Aクラスとします)を作成した後に
そのAクラスを利用(というか初期化)するためにインスタンス化をしますよね?
Aクラスのインスタンス化を継承関係のないところ(newがないところ)で行い
インスタンス化されたAクラスの情報の変更等を行うためのクラスを
派生の派生などで扱うということでしょうか…?
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 17:05
by softya(ソフト屋)
門番 さんが書きました:>>softyaさん
共通の情報を持つクラス(Aクラスとします)を作成した後に
そのAクラスを利用(というか初期化)するためにインスタンス化をしますよね?
Aクラスのインスタンス化を継承関係のないところ(newがないところ)で行い
インスタンス化されたAクラスの情報の変更等を行うためのクラスを
派生の派生などで扱うということでしょうか…?
説明がよくわからないのですが、継承は構造を引き継ぐだけなので別インスタンスであればデータは引き継がれません。
インスタンスごとに独立しているものとして扱ってください。
つまり、共通のデータを持つ専用のクラス構造のインスタンスが必要なのでは?と言うことです。
説明の中に継承が出てくるのが良くわからないです。
なんのために継承するのでしょうか? 無意味な継承はプログラムを複雑怪奇にするだけです。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 17:53
by 門番
>>softyaさん
すみません、かなり酷い文を書いていました…
インスタンスはそれぞれ独立していて
内部のものもそのインスタンス固有のもの
ということは承知いたしました
少し混乱しながらですが、
共通のデータを持つインスタンスを基底クラスで作成し、
その基底クラスを継承すれば
派生クラスでもそのインスタンスを
同じ場所にあるインスタンスとして、扱えるのでしょうか?
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 18:14
by h2so5
「共通のデータを持つインスタンス」と「同じ場所にあるインスタンス」の意味を明確にしてください。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 18:15
by hide
用語を整理したほうが良いかと思います。
継承関係はインスタンス化より前にプログラムに書いてしまうわけですから
インスタンスを作成して継承する、という時点でなにかがおかしいです。
それと、場所という言葉が曖昧です。何をさして場所と言っているのか伝わりません。
なんかの入門書にでも書いてあったのでしょうか?
それとも門番さんが独自に使っている単語ですか?
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 18:26
by usao
structと並べて書いてみました.
コード:
struct S{ int data; }; //S型インスタンスはdataという変数をメンバに持つ
...
S a;
S b;
//ここで, a.data と b.data は別のもの.
コード:
class Base{ int data; }; //Base型インスタンスはdataという変数をメンバに持つ
class Deriv : public Base {}; //Deriv型インスタンスはdataという変数をメンバに持つ
...
Deriv a;
Deriv b;
//a.data と b.data は別のもの.
Base c;
Base d;
//a.data,b.data, c.data, d.data は全て別のもの.
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 19:12
by 門番
>>h2so5さん
共通のデータを持つインスタンス、は
他のインスタンスで参照したい変数と関数をまとめたクラスをインスタンス化したもの
同じ場所にあるインスタンス、は
初めにクラスをインスタンス化したときに付与されるメモリアドレスと
同じメモリアドレスを指しているインスタンス
という意味であります
>>hideさん
そうなのですか?
だとしたら自分はかなり間違ったプログラムを書いているかもしれないですね・・・
場所についてですが、メモリアドレスという意味で使っておりました
自分が独自に使っている単語なので曖昧な表現で申し訳ありません
>>usaoさん
ソースコードありがとうございます
一応それらが全て別物のということは把握しておりますが・・・
クラスとインスタンスの使い方を間違えてるのかもしれないですね・・・
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 19:21
by usao
>ソースコードありがとうございます
>一応それらが全て別物のということは把握しておりますが・・・
>クラスとインスタンスの使い方を間違えてるのかもしれないですね・・・
あなたのやろうとしていること(?)を,このような簡単化したソースの形で説明されてみてはいかがでしょうか.
私があなたの文章を読んだ感じだと,
>共通のデータを持つインスタンス
というのが,Base::data に相当するもの
(この例では Base::dataはintですが,これがintではなく何らかのクラス型だとして)
なのか?と思ったのですが,違うみたいですね.
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 19:31
by hide
Characterクラスの派生である敵クラスのインスタンス 敵Aさん と 敵Bさん が
それぞれ別なインスタンスを参照してしまっている、ということですかね?
で、その参照先がまとめ?クラス?でしょうか
参照関係の作り方がおかしい気がしてなりません。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 19:48
by softya(ソフト屋)
コードでイメージを書いてみました。
こういう事を考えているという事でよろしいですか?
コード:
// 継承と同じようなC言語で分かる範囲のものとして構造体を使います。
// 基底となるBase
struct Base {
int val;
};
// Baseを内包するA。継承に近いイメージだと思ってください。
struct A {
struct Base base;
int a1;
};
// Baseを内包するB
struct B {
struct Base base;
int b1;
};
int main() {
// それぞれのインスタンスを生成します。
struct Base base = {123};
struct A a;
struct B b;
// これが全部同じ値を持つと考えているということでしょうか?
printf( "base.val=%d a.base.val=%d b.base.val=%d",base.val,a.base.val, b.base.val);
return 0;
}
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 20:51
by 門番
>>usaoさん
後者のBase::dataに相当するものに近い気がいたします
簡単化したソースを下のほうに書いてみます
>>hideさん
あ、いえそういうわけではございません
Scene1-1や2-1で味方まとめを参照したいのですが
参照のやり方が間違っているのか、Sceneの方の作り方がおかしいのか
それぞれのSceneで別のメモリアドレスの味方まとめを参照してしまっているということです
>>softyaさん
はい、同じ値であると考えております
コード:
class Chara{int i;}//他から参照したいクラス
class Base{}
//Baseを継承しているAB
class A :public Base{}//参照をするクラス
class B :public Base{}//参照をするクラス
int main(){
A a;
B b;
//ここでa,bからCharaを参照したいのです
return 0;
}
書いていて何かおかしい気がするのは感じるのですが・・・
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 21:01
by softya(ソフト屋)
>>これが全部同じ値を持つと考えているということでしょうか?
>はい、同じ値であると考えております
実際に動かして試してみると分かりますが同じ値は持っておりません。
C++のクラスもこれと同じです。
C言語でも同じ値を持つと思っているのなら構造体自体の理解が怪しいです。
実際としては、class Charaのインスタンスの参照をclass Aやclass Bのコンストラクタで得て参照のメンバ変数(class Chara)に代入すればclass Aやclass Bがclass Charaのインスタンスの参照を保持することになるので、とりあえず解決する気もしますがオブジェクト指向としてどうなの!ってのはあります。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 21:16
by 門番
>>softyaさん
あら・・・これは今まで勘違いをしていたようです・・・
お恥ずかしい話です
なるほど・・・そういうやり方もあるのですね
しかし、オブジェクト指向としてあまりよろしくないようですね
オブジェクト指向として解決していくのであれば
どのようにプログラムを設計し直すとよいのでしょうか・・・?
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 21:23
by softya(ソフト屋)
> どのようにプログラムを設計し直すとよいのでしょうか・・・?
それは各オブジェクトの関係で決まります。
ただ、上位の情報を下位のオブジェクトが直接参照するのは間違っている場合が多いです。
「味方の統合クラス」が個々の「味方クラス」のインスタンスを保持しているは良いですが、「味方クラス」から「味方の統合クラス」のインスタンスを参照してはいけません。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 21:41
by 門番
>>softyaさん
上位の情報を下位のオブジェクトが直接参照するのは間違っていることが多い
肝に銘じておきます
だいぶ整理がついてきましたが、最後に、
インスタンス化していないクラスの中にある関数を
他のクラスで呼ぶためには
インスタンス化していないクラスの中の関数にstatic修飾子を付けて静的にしておいて
クラス名::関数名 で呼び出す
という方法でよろしいでしょうか?
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 21:45
by softya(ソフト屋)
>インスタンス化していないクラスの中の関数にstatic修飾子を付けて静的にしておいて
>クラス名::関数名 で呼び出す
>という方法でよろしいでしょうか?
よいですが、その場合メンバ変数もstaticじゃないと保持できませんよ。
ただ、意図次第ではクラスにする必要するなくてC言語の関数と同じ作りで済む場合が多いです。
無理してクラスにしないようにしましょう。関数を使って良いのです。
【補足】
staticメンバからは、インスタンス化したクラスのメンバ変数を参照できません。
複数のインスタンスのどれを参照してよいか分かりませんものね。
インスタンス化されているかも知らないわけです。
あとデザインパターンのシングルトンパターンも選択肢に入れましょう。
どちらを選ぶかは、オブジェクトの性質次第です。
Re: 複数のクラスから特定のクラスを参照したい
Posted: 2014年6月26日(木) 22:11
by 門番
>>softyaさん
はい、承知いたしました
staticメンバからは、インスタンス化したクラスのメンバ変数を参照できない
これも記憶しておきます
シングルトンパターンですか・・・初めて聞きましたが、
実体(インスタンス)が1つであることを保障する書き方
のようですね、もう少し理解した上でプログラムを書いていきたいと思います
自分の勘違いや理解不足が原因で今回の質問の内容をやろうとしていたみたいです
とりあえず、今回の質疑応答を基にプログラムを書き直していきます
皆様丁寧にご回答いただきありがとうございました