C++ 初心者のためのBattleクラスの理解について

このQ&Aのポイント
  • C++の初心者がBattleクラスの理解について質問しています。
  • 質問文章中のenum ResultOfFightとFight関数の意味が分からないとのことです。
  • 回答者による解説や補足が求められています。
回答を見る
  • ベストアンサー

C++ 初心者です

enum ResultOfFight { PLAYERWIN, ENEMYWIN, DRAW }; class Battle { public: ResultOfFight Fight(Player* player, Trainer* enemy); ResultOfFight Fight(Player*player, Monster* monster) { Toumei x; x.PlusMonster(monster); return Fight(player,&x); } } 今時分はvoid Battle::Fight(){・・・・}の中身を書いているですが (1)enum ResultOfFight { PLAYERWIN, ENEMYWIN, DRAW }; への返し方 (2) ResultOfFight Fight(Player*player, Monster* monster) { Toumei x;   x.PlusMonster(monster);     return Fight(player,&x); ←これが何を意味しているかが分からない } この二つがよく分かっていません 理解していないばかりに、分かりづらく質問をしているのかもしれませんが どなたかご教授してくださると嬉しいです

質問者が選んだベストアンサー

  • ベストアンサー
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

(1)とりあえず「への返し方」は「の返し方」でしょうか? そうだとすると、{...}の中のいずれかを返せばいいのです。 これは、その値そのままを書かなくてはならないというのではなくそのような値を返す関数を呼び出した結果を返してやってもいいのです。 (2)見たとおり、Fight(player,&x)の結果をこの関数の戻り値にしているだけです。 …とはいえ、全くの初心者にはちょっと分かりづらいテクニックを使っているようです。 テクニックその1:関数/メソッドのオーバーロード C++では引数の型が違えば同じ名前の関数やメソッドを複数定義できます。これをオーバーロード(多重定義)といいます。 あなたが質問されている関数はResultOfFight Fight(Player*player, Monster* monster)で、それと別に直前でResultOfFight Fight(Player* player, Trainer* enemy)が宣言されています。2番目の変数の型が違うので、この2つは別の関数です。 テクニックその2:クラスの継承 しかし、関数呼び出しの引数として渡している型はToumei*で、Monster*でもTrainer*でもありません。 これはクラス名等からの憶測なのですが、このソースはポケモンのようにモンスターをトレーニングしてトレーナー同士で対戦するゲームのソースの一部ではないのでしょうか。 だとしたら、トレーナー同士の対戦と野良モンスターとの戦いで戦闘ロジックを共通化したいところですが、(これまたクラス名と問題の関数の処理からの推察ですが)野良モンスターとの戦いを「透明なトレーナーがいる」ものとしてトレーナー同士の対戦ロジックに渡して共通化しているように思います。 親クラスのポインタには子クラスのポインタが問題なく代入できますので、TrainerがToumeiの親クラスであるならば2番目がTrainer*型のほうのFightが呼び出されます。 …でも、あなたが質問された事柄はC++の学習をきちんとしていれば簡単なことです。きついことを言うようですが、もう一度C++の勉強をしなおしてからこのソースに手をつけたほうがいいかと思います。

oceancat
質問者

お礼

ありがとうございました

oceancat
質問者

補足

(1)とりあえず「への返し方」は「の返し方」でしょうか? そうだとすると、{...}の中のいずれかを返せばいいのです。 これは、その値そのままを書かなくてはならないというのではなくそのような値を返す関数を呼び出した結果を返してやってもいいのです。 すいません 具体的な例を教えていただけませんでしょうか? またこういったものを勉強するにあたって 参考になるようなサイトというものをご存じないでしょうか?

その他の回答 (2)

回答No.3

http://homepage2.nifty.com/well/Index.html 例えばこのサイトとか参考になります。 読んでも分からない部分があるようなら回答します。

oceancat
質問者

お礼

ありがとうございました

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

サイトを使って勉強するのもいいですが、 まずは入門書を1冊読み通してみてはどうでしょうか。 ゲームプログラミング(らしきもの)に手を出すのは、 その後でも遅くないと思います。 ていうか、基本ができてなければ、応用問題は解けないですよね。

oceancat
質問者

お礼

ありがとうございました

関連するQ&A

  • C++ 初心者です

    enum ResultOfFight { PLAYERWIN, ENEMYWIN, DRAW }; class Battle { public: ResultOfFight Fight(Player* player, Trainer* enemy); }; というものがあるのですが ResultOfFight Fight(Player* player, Trainer* enemy); という部分の定義の仕方?と言いますか なぜこのように書くことができるのかが分かりません どなたかご教授していただけませんでしょうか? 学校の授業でC++しかやっていないので、 C言語はやったことがありません・・・・orz

  • C++/CLIでクラス内の要素を相互利用する方法

    C++/CLIでクラスの中に定義された構造体等を、複数のクラス間で相互利用したいのですが、そのようなことは可能なのでしょうか。 とりあえず以下のコードを見ていただきたいのですが、 ref class class1; ref class class2; ref class class1 { public:  enum struct enum1  {   aa,bb  };  void func1a(class1^ obj){} // 1. OK  void func2a(class2^ obj){} // 2. OK  void func1b(class1::enum1 e){} // 3. OK  void func2b(class2::enum2 e){} // 4. ERROR }; ref class class2 { public:  enum struct enum2  {   aa,bb  };  void func1a(class1^ obj){} // 5. OK  void func2a(class2^ obj){} // 6. OK  void func1b(class1::enum1 e){} // 7. OK  void func2b(class2::enum2 e){} // 8. OK }; これの4.がコンパイルエラーになります。 このような構造を定義することはできないのでしょうか。

  • C++初心者です

    C++初心者です どうも行き詰ってしまったのでまた投稿させていただきました。 文字数が足りないため前回の投稿から何を作ろうとしているか見ていただけると嬉しいです。 http://okwave.jp/qa/q5993632.html どうか間違っているところご指摘お願いできないでしょうか。 最後の部分は根本的にできていないので助けていただけると幸いです #include <iostream> #include <string> #include <cstdlib> #include <ctime> #include <map> using namespace std; class Cards { string Name; string Explain; public: Cards(const string e):Explain(e){} const string GetExplain() const {return Explain;} }; class Game { public: static const int KindsOfCards = 4; virtual Cards* SetCard(); }; Cards* Game::SetCard() { switch(rand() % KindsOfCards) { case 1: return new Square; case 2: return new Half; case 3: return new Reverse; case 4: return new Plus; } } class Square : public Cards { public: Square() : Cards("「二乗」 (二乗する)"){} virtual void Excute(); }; class Half : public Cards { public: Half() : Cards("「半分」 (2分の1にする)"){} virtual void Excute(); }; class Reverse : public Cards { public: Reverse() : Cards("「反転」 (符号を反転する)"){} virtual void Excute(); }; class Plus : public Cards { public: Plus() : Cards("「Plus17」", "(17を加える)"){} virtual void Excute(); }; void Square::Excute() { Now[i+1] = Now[i]*Now[i]; return Now[i+1]; } void Half::Excute() { Now[i+1] = Now[i]/2; return Now[i+1]; } void Reverse::Excute() { Now[i+1] = Now[i]*(-1); return Now[i+1]; } void Plus::Excute() { Now[i+1] = Now[i]+(17); return Now[i+1]; } int main() { int Level; Level = 3; srand((unsigned) time(NULL)); map<int,int> Target; for(int i = 0; i <= Level; i++) { Target[i]; } int Now; int T(int t) { public: Cards* c = SetCard(); Target[0](int t0){t0 = rand() % 100;} Target[0] = Now; Target[1](int t1){t1 = c->Excute();} target[2](int t2){t2 = c->Excute();} Target[3](int t3){t3 = c->Excute();} target[3] = t; } cout << "●所有しているカード●" << endl; for(int i = 1; i <= Level; i++) { cout << i << ":" << c->GetExplain() << endl; } cout << "目 標 値:" << T << endl; cout << "現在の数値:" << Now << endl; }

  • enumをintとして扱う必要があるパターンはあるのでしょうか。

    enumをintとして扱う必要があるパターンはあるのでしょうか。 よく enum ENUM_SAMPLE {  A,  B,  C, }; class CLASS_SAMPLE { private:  int type; // ENUM_SAMPLEのA,B,Cしか入らない public:  int GetType(){ return type; } }; という記述を良く見かけます。 class CLASS_SAMPLE { private:  ENUM_SAMPLE type; // ENUM_SAMPLEのA,B,Cしか入らない public:  ENUM_SAMPLE GetType(){ return type; } }; のほうが良いのではないか思うのですが、intで定義することによる利点が何かあるのでしょうか。 あと、過去に // bcc利用時に問題があるのでintに変更しました int CLASS_SAMPLE::GetType {  return type; } というコメントがついたソースを見たことがあり、 自分でbccを使ってenumを返すように修正してテストしてみたことがあるのですが、何が問題なのか見つけることが出来ませんでした。 enum名を直接使用した場合に問題が発生することがあるのか、またどのような問題が発生することがあるのか、回答お願いします。

  • C#で参照

    C#で参照 こんにちは。 例えば、C++で class A { int &x; public: A(int &_x):x(_x){} public: void disp() { std::cout<<x<<std::endl; } }; void func() { int x=100; A a(x); a.disp(); x=200; a.disp(); } とすると、a.xとxとを連動させることができますが、同様のことをC#で行うにはどうすればよいのでしょうか? int x=100; の定義を変えずに行うことは可能でしょうか? よろしくお願いします。

  • コンパイルエラー: LNK2001

    今、ベクトル計算を簡単にするクラスを作ってみようとしています。 //vector3.h template<class TT> class vector3{ public:   enum{NUM=3};   TT x[NUM];   void set(const TT *vv)void set(const TT *vv){     int i;     for(i=0;i<NUM;i++){       x[i]=vv[i];     }   } }; のように、set関数をクラスの中に書いていると問題無いのですが、以下のように、 //vector3.h template<class TT> class vector3{ public:   enum{NUM=3};   TT x[NUM];   void set(const TT *vv); }; //test.cpp #include"vector3.h" template<class TT> void vector3<TT>::set(const TT *vv){   int i;   for(i=0;i<NUM;i++){     x[i]=vv[i];   } } と、cppファイルの中に書き換えると以下のようにエラーが出るようになります。 error LNK2001: 外部シンボル ""public: void __thiscall vector3<double>::set(double const *)" (?set@?$vector3@N@@QAEXPBN@Z)" は未解決です。 fatal error LNK1120: 外部参照 1 が未解決です。 これはいったい何故なのでしょうか? 使用しているのはVisualC++2008ExpressEditionです 宜しくお願いします。

  • C++について教えてください。(初心者です)

    現在C++についての学習を進めているのですが、 2項演算子のオーバーロードで理解できないところがありますので、よろしかったらご教授ください。 //+をcoordクラスに対してオーバーロードする #include<iostream> using namespace std; class coord{ int x,y; public: coord() {x=0;y=0;} coord(int i,int j) {x=i;y=j;} void get_xy(int &i,int &j) {i=x;j=y;} coord operator+(coord ob2); }; //+をcoordクラスに対してオーバーロードする coord coord::operator+(coord ob2) { coord temp; temp.x = x + ob2.x; temp.y = y + ob2.y; return temp; } int main() { coord o1(10,10),o2(5,3),o3; int x,y; o3 = o1 + o2; o3.get_xy(x,y); cout << "(o1+o2) X:" << x << ",Y:" << y << endl; return 0; } この文の中で、o3.get_xy(x,y);というコードがありますが、 ここの部分がよくわからないのです。 そもそも、引数としてx,yがありますが、これはprivateメンバを 見に行きなさい。っと言っているのでしょうか? main()の中から直接使っている?? それとも?? すいません。この辺の理解が薄いようなので、2項演算子のオーバーロードとは関係ないかもしれませんが、教えてください。 よろしくお願いします。

  • 【C++】アドレス演算子について質問です。

    アドレス演算子について質問です。 下記のように"&"を関数名の前に付けた場合下記のように出力されます。 &グローバルメソッド:002E1226 &クラス::メンバメソッド:1 1行目はグローバルメソッドなので実態が存在するのでメソッドのアドレスが表示されている。 2行目は実態が存在しないと思うのですが、あってますでしょうか? また、何故1が表示されてしまうのでしょうか? -------------------------------------------------------- #include "stdafx.h" #include <iostream> using namespace std; class Class1{ public: void f(){ return; } }; void Func1(){ return; } int main() { cout << "&グローバルメソッド:" << &Func1 <<endl; cout << "&クラス::メンバメソッド:"<< &Class1::f <<endl; getchar(); return 0; }

  • コンパイルエラーについて

    次のようなプログラムをうつと以下のようなコンパイルエラーが表示されます。 main(){ int a[2][3]; struct monster monster[5] = { { 1, "a", "b", 1, 2, 120, 80, "v", 60, 60, 60, 100}, { 2, "a", "b", 2, 3, 120, 80, "w", 60, 60, 60, 100}, { 3, "a", "b", 3, 4, 120, 80, "x", 60, 60, 60, 100}, { 4, "a", "b", 4, 5, 120, 80, "y", 60, 60, 60, 100}, { 5, "a", "b", 5, 1, 120, 80, "z", 60, 60, 60, 100}, }; struct monster monster2[5] = { { 1, "a", "b", 1, 2, 120, 80, "v", 60, 60, 60, 100}, { 2, "a", "b", 2, 3, 120, 80, "w", 60, 60, 60, 100}, { 3, "a", "b", 3, 4, 120, 80, "x", 60, 60, 60, 100}, { 4, "a", "b", 4, 5, 120, 80, "y", 60, 60, 60, 100}, { 5, "a", "b", 5, 1, 120, 80, "z", 60, 60, 60, 100}, }; inputmonster(a, monster); printf("これからバトルを開始します\n\n"); printf("player1は%sをくりだした。\n", monster[a[0][0]-1].name); printf("player2は%sをくりだした。\n", monster2[a[1][0]-1].name); battle(a, monster, monster2); return 0; } void inputmonster(int x[][3], struct monster monster[]) { int i, s, t, m, n; for(t = 0; t < 2; t++){ s = 0; while (s < 1){ printf("player%dは好きなモンスターを3つ選んでください\n\n", t+1); for (i = 0; i<3; i++){ printf("%d体目を選んでください。\n\n", i+1); for(m = 0; m < 5; m++) printf("%d, %s\n", m+1, monster[m].name); scanf("%d", &x[t][i]); printf("%d体目 : %s\n\n", i+1, monster[x[t][i] - 1].name); } printf("これでよろしいですか?\n"); for(i = 0; i<3; i++) printf("%d体目 : %s ", i+1, monster[x[t][i] - 1].name); printf("1、はい 2、いいえ\n"); scanf("%d", &n); if(n == 1) s = 1; else s = 0; } } } monsterbattle.c: 関数 ‘main’ 内: monsterbattle.c:499:15: 警告: 互換性のないポインタ型から 1 番目の ‘inputmonster’ の引数に渡しています inputmonster(&a, monster); ^ monsterbattle.c:27:6: 備考: expected ‘int * (*)[3]’ but argument is of type ‘int (*)[2][3]’ void inputmonster(int *x[][3], struct monster monster[]) ^ monsterbattle.c:507:9: 警告: 互換性のないポインタ型から 1 番目の ‘battle’ の引数に渡しています battle(a, monster, monster2); ^ monsterbattle.c:232:6: 備考: expected ‘int *’ but argument is of type ‘int (*)[3]’ void battle(int a[2], struct monster monster[], struct monster monster2[]) ^ すいませんが、あまりエラーの詳細がわからず困っています。 どこをどのように変更すべき表示なのでしょうか? よえろしくお願いします。

  • C++基底クラスに戻り値の異なる関数が宣言されている場合

    こんにちは。 質問させてください。 以下のようなコードがあったとします。 class Base1 { public:   virtual int get()=0; }; class Base2 { public:   virtual float get()=0; }; class Ex : public Base1, public Base2 { public:   int get(){return 0;}   float get(){return 0.0f;} }; void main() { } このプログラムをコンパイルすると 「'Ex::get': オーバーライドする仮想関数の戻り値の型が異なり、'Base1::get' の covariant ではありません。」 というエラーが出てしまいます。 関数の名前と引数が同じで戻り値だけが異なる場合はエラーが出るのはわかるのですが、基底クラスのBase1、Base2は変更不可能だとするとどのように回避すればいいのでしょうか? よろしくお願いします。 /*   WindowsXP Professional SP3   VisualStudio2005 AcademicEdition */

専門家に質問してみよう