ページ 1 / 1
structの変数が多重定義される
Posted: 2012年9月20日(木) 08:54
by Dexs
テンプレートというファイルを作り、ここに初期ステータスを定数で予め書いておこうと思ったのですが、
これらを使おうと複数のファイルでincludeすると多重定義といわれます。
多分下のコードが悪いと思うのですが、ファイルを2つに分けて、
Templateの宣言ファイル→Templateの定義ファイル→使う
という方法ならできますか?
コード:
#ifndef Template
#define Template
typedef struct {
double HitPoint;
double BodySize;
double WalkSpeed;
double DashSpeed;
}Character_t;
//Character
Character_t CharacterClass_t[3]={
{100.0, 20.0, 7.0, 12.0},
{100.0, 20.0, 5.0, 10.0},
{100.0, 20.0, 5.0, 10.0}
};
#endif
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 09:49
by box
Dexs さんが書きました:
コード:
//Character
Character_t CharacterClass_t[3]={
{100.0, 20.0, 7.0, 12.0},
{100.0, 20.0, 5.0, 10.0},
{100.0, 20.0, 5.0, 10.0}
};
ヘッダーファイルでは
コード:
extern Character_t CharacterClass_t[3];
のように書いて、「どこかで実体を定義した構造体の配列を使います」と宣言しておきます。
そして、上に引用した構造体の配列の実体を「どこか1ヶ所だけで」定義しておきます。
そうすればうまくいくような気がします。
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 17:36
by Dexs
すいません、カプセル化を目標にしているのでextern(グローバル変数?)はあまり使いたくありません。
Template.hというファイルをincludeしたファイル内だけで使いたいです。
enum{chara1,chara2,chara3};
const double CharacterHitPoint[3]{100.0,100.0,100.0};
const double CharacterBodySize[3]{20.0,20.0,20.0};
const double CharacterWalkSpeed[3]{7.0,5.0,5.0};
const double CharacterDashSpeed[3]{12.0,10.0,10.0};
のような感じだったのですが、グループ化したほうがわかりやすいんじゃないかと思い構造体を使いました。
(カプセル化というからには構造体ではなくクラスのprivateメンバで初期化用の定数を持っておき、そのクラスを継承することで実現するべきなのかもしれませんが・・・)
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 17:47
by softya(ソフト屋)
ヘッダに構造体の実体データ定義をしてはいけませんよ。
そもそも初期値のデータなら、どれかcpp内のファイルに閉じ込められるのではでしょうか? それでこそカプセル化だと思います。
初期値データをあちこちで参照すること自体がカプセル化からするとマズイです。
ちなみに、Templateと言う名前はC++のテンプレート機能を連想させるので避けたほうが良いと思います。
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 18:52
by Dexs
softya(ソフト屋) さんが書きました:ヘッダに構造体の実体データ定義をしてはいけませんよ。
確かに間違ってました。すいません。
softya(ソフト屋) さんが書きました:どれかcpp内のファイルに閉じ込められるのではでしょうか?
ちょっとよくわからないのですが、例えばCharacter::Initialize()という関数があって、その中に初期値データを参照するような処理を作るということでしょうか?
No1に書いておくべきことでしたが、
・キャラクターの初期値データはプログラム内に定数で、一元管理したい
という設計にしたいです。(バランス調整が楽ですし・・・)
これはカプセル化というコンセプトに好ましくない方法なのでしょうか?
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 18:55
by Dexs
Templateが、C++の機能の名称でまずいということなのでInitialStateに変えましたが、
Operator(プレイヤー・AIなどの操作者)やClass(キャラクターの職業)
もまずそうですね・・・
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 19:01
by softya(ソフト屋)
私は、初期値はファイル化したほうがバランス調整が楽だと思いますがいかがでしょう。
それと一元管理なら全キャラクタの初期値を持つだけのクラスかキャラクタを管理するクラスではダメでしょうか?
キャラクタを管理するクラスならキャラクタのインスタンス生成まで面倒を見ても良いと思います。
>Operator(プレイヤー・AIなどの操作者)やClass(キャラクターの職業)もまずそうですね・・・
マズイと思います。
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 22:44
by Dexs
softya(ソフト屋) さんが書きました:私は、初期値はファイル化したほうがバランス調整が楽だと思いますがいかがでしょう。
それと一元管理なら全キャラクタの初期値を持つだけのクラスかキャラクタを管理するクラスではダメでしょうか?
初期値だけを持つクラスというのはキャラクタのインスタンスを一つ定数で作って、どこかで持っておくということでしょうか?
Character.h → Character.cpp
↓ ↓継承
↓ IniChara.cpp
↓ ↓値のコピー
Character実装??
クラスでゲーム全体の状態遷移を管理していると、キャラクタを管理するクラス=その場面(シーン)になるのでしょうか
コード:
class Stage{
private:
vector<Character*> character;
public:
Stage();
};
//キャラクターはステージでインスタンス化されて初期化される?
Re: structの変数が多重定義される
Posted: 2012年9月20日(木) 23:06
by softya(ソフト屋)
>初期値だけを持つクラスというのはキャラクタのインスタンスを一つ定数で作って、どこかで持っておくということでしょうか?
私の案は、キャラクタは複数の種類がありそれぞれ別の初期値があるとします。
でキャラクタの初期値管理クラスを作りすべてのキャラクタの初期値は、そこで管理されます。シングルトンで良いでしょう。
※ 私は初期値のファイル化を推奨します。
各キャラクタクラスのインスタンス生成時にコンストラクタでキャラクタの初期値管理クラスから初期値を得て初期化するという仕組みです。
(使い方の例)
キャラクタのインスタンス = new キャラクタ種類別のクラス
でクラスのコンストラクタでキャラクタの初期値管理クラスから初期値を貰うわけです。
あるいは、キャラクタを管理するクラスでキャラクタのインスタンス生成まで面倒を見て初期値もそこで与えるという手もあります。これもシングルトンかな。
(使い方の例)
キャラクタのインスタンス = キャラクタを管理するクラス.キャラクタ生成メソッド(キャラクタの種類);
まぁ、例なので他にも色々考えられると思いますよ。
Re: structの変数が多重定義される
Posted: 2012年9月21日(金) 00:11
by Dexs
softya(ソフト屋) さんが書きました:>初期値だけを持つクラスというのはキャラクタのインスタンスを一つ定数で作って、どこかで持っておくということでしょうか?
私の案は、キャラクタは複数の種類がありそれぞれ別の初期値があるとします。
でキャラクタの初期値管理クラスを作りすべてのキャラクタの初期値は、そこで管理されます。シングルトンで良いでしょう。
※ 私は初期値のファイル化を推奨します。
各キャラクタクラスのインスタンス生成時にコンストラクタでキャラクタの初期値管理クラスから初期値を得て初期化するという仕組みです。
(使い方の例)
キャラクタのインスタンス = new キャラクタ種類別のクラス
でクラスのコンストラクタでキャラクタの初期値管理クラスから初期値を貰うわけです。
あるいは、キャラクタを管理するクラスでキャラクタのインスタンス生成まで面倒を見て初期値もそこで与えるという手もあります。これもシングルトンかな。
(使い方の例)
キャラクタのインスタンス = キャラクタを管理するクラス.キャラクタ生成メソッド(キャラクタの種類);
まぁ、例なので他にも色々考えられると思いますよ。
なるほど、ソフト屋さんの言うとおりファイル化のほうがわかりやすいと思えてきました。
といっても具体的な方法があまり思い浮かばないのですが、
ファイルパスを定義したstring定数配列などをキャラクターのコンストラクタなどで添字で分岐して読み込ませるぐらいしか思い浮かばないです。
→ const string charini[1]={"\char1.dat"};
もしよければ適切な方法を教えて下さい。
Re: structの変数が多重定義される
Posted: 2012年9月21日(金) 00:20
by softya(ソフト屋)
毎回初期化値を読んだら時間が勿体無いので、そういうのはキャラクタ初期値の管理クラスのコンスタラクタで一気読みするとかが良いと思います。 ← 誤字修正
excelなど作ったcsvをコンストラクタでfstreamで要素に分解しつつvectorの構造体配列に蓄えて置けばよいだけです。
ステージ別にする必要が無いのならですけどね。絶対ステージ別に分けるのでしょうか?
Re: structの変数が多重定義される
Posted: 2012年9月21日(金) 10:38
by Dexs
自分の考えだと初期値管理クラスは(ステージ管理クラスのコンストラクタで)キャラクターのインスタンス化直前にファイルを読み込む感じで、同じ位置に存在するのですが、
それでも速度の違いがでるのでしょうか?(メニュー画面やステージ選択画面に初期値管理クラスを置きたくない)
※以下の処理がステージ管理クラスのコンストラクタで全部行われます。
ファイル ファイル
↓ ↓↓↓↓
初期値管理クラス キャラクターインスタンス化
↓↓↓↓
キャラクターインスタンス化
ステージ別にわけることは考えていません。
もしキャラクターのパラメータを初期値から変えたい時は"パワーアップ"という要素で、初期値に加算しようと思います。
※パワーアップのデータは、セーブデータファイルとステージファイルの敵キャラクターの情報と一緒に入ってます。
Re: structの変数が多重定義される
Posted: 2012年9月21日(金) 11:01
by softya(ソフト屋)
>自分の考えだと初期値管理クラスは(ステージ管理クラスのコンストラクタで)キャラクターのインスタンス化直前にファイルを読み込む感じで、同じ位置に存在するのですが、
>それでも速度の違いがでるのでしょうか?(メニュー画面やステージ選択画面に初期値管理クラスを置きたくない)
シングルトンにすれば位置は気にしなくて良いです。
インスタンスは唯一無二なので、どこからでもインスタンスを参照可能です。
それと速度の問題ですが一般論としての見解ですので、私はDexsさんがどういうタイミングでキャラクタを生成するつもりなのかは理解せずに説明しているという状況です。
この話だとステージのコンストラクタでステージに登場するすべてのキャラクタのインスタンスが生成されると考えて良いのでしょうか?
だとしても、1回のopenでファイルを連続で読む(初期値管理クラス)のと毎回キャラクターがopenして自分のデータまで読み飛ばす(キャラクターのコンストラクタ)では速度に差がでます。
敢えて時間が無駄になりそうな設計にしなくて良いと思いますが如何でしょうか?
Re: structの変数が多重定義される
Posted: 2012年9月21日(金) 20:39
by Dexs
なるほど、おっしゃるとおりです。
疑問が解決したので解決とさせて頂きます。
boxさんSoft屋さんありがとうございました!