class BossAction {
protected:
int t;
int t_limit;
void LimitCnt();
public:
BossAction() {t = 0; };
virtual void Action(SpriteData &sp , BossData &bs) = 0;
int ReturnTimeLimit() {return t_limit; };
};
class BossActionIn : public BossAction {
public:
BossActionIn():BossAction() { t_limit = 30; };
virtual void Action(SpriteData& sp, BossData& bs)override;
};
class BossActionTurn : public BossAction {
public:
BossActionTurn() :BossAction() {};
virtual void Action(SpriteData& sp, BossData& bs)override;
};
class BossActionWait : public BossAction {
public:
BossActionWait() :BossAction() { };
virtual void Action(SpriteData& sp, BossData& bs)override;
};
class BossAction01 : public BossAction{
public:
BossAction01() :BossAction() { t_limit = 30;};
virtual void Action(SpriteData& sp, BossData& bs)override;
};
class BossAction02 : public BossAction {
public:
BossAction02() :BossAction() {t_limit = 60;};
virtual void Action(SpriteData& sp, BossData& bs)override;
};
class BossAction03 : public BossAction {
public:
BossAction03() :BossAction() {t_limit = 30;};
virtual void Action(SpriteData& sp, BossData& bs)override;
};
class BossAction04 : public BossAction {
public:
BossAction04() :BossAction() {t_limit = 120; };
virtual void Action(SpriteData& sp, BossData& bs)override;
};
//以下は本来はBossクラスのupdate()メソッドに内に書かれているです部分です。
switch (bs.act_id) {
case -2:
if (typeid(bossaction) != typeid(BossActionWait))bossaction.reset(new BossActionWait);
break;
case -1:
if (typeid(bossaction) != typeid(BossActionTurn))bossaction.reset(new BossActionTurn);
break;
case 0:
if (typeid(bossaction) != typeid(BossActionIn))bossaction.reset(new BossActionIn);
break;
case 1:
if (typeid(bossaction) != typeid(BossAction01))bossaction.reset(new BossAction01);
break;
case 2:
if (typeid(bossaction) != typeid(BossAction02))bossaction.reset(new BossAction02);
break;
case 3:
if (typeid(bossaction) != typeid(BossAction03))bossaction.reset(new BossAction03);
break;
case 4:
if (typeid(bossaction) != typeid(BossAction04))bossaction.reset(new BossAction04);
break;
}
bossaction->Action(sp , bs);
ループ内でのオブジェクトの動的確保について
ループ内でのオブジェクトの動的確保について
STGを作っています。ボスの行動パターンをBossActionクラスという抽象クラス化し、そのクラスへのポインタスマートポインタ(bossaction)から派生の行動パターンをループ内で動的確保するプログラムを作っています。行動id(bs.act_id)によって行動パターンを場合分けするようにしているのですが、ループ内でそのまま確保すると延々と確保し続けてしまうので、idが切り替わった瞬間だけ確保するようにしなければならないと思い、typeidを使ってポインタがその行動パターンを指してない時のみ確保するように試みたのですが、実行してみると結局延々と確保し続けているようです。改善策を教えていただけると幸いです。「bossaction->Action(sp , bs);」がボスを動かすメソッドです。
- spaaaark・∀・
- 記事: 66
- 登録日時: 10年前
- 住所: 埼玉
- 連絡を取る:
Re: ループ内でのオブジェクトの動的確保について
検証してみましたが、typeidが一致するのはポインタの実体を入れたときだけのようです。
なのでポインタの実体を参照するようにするとうまく行くと思います。
(ただし、ぬるぽにはご注意ください。)
検証コード:
https://ideone.com/4f0Eht
なのでポインタの実体を参照するようにするとうまく行くと思います。
(ただし、ぬるぽにはご注意ください。)
検証コード:
https://ideone.com/4f0Eht
クリエイティブな生活で刺激的な毎日を!
Re: ループ内でのオブジェクトの動的確保について
spaaaark・∀・さん
返信ありがとうございます。お陰様でtypeidの使い方が間違っていたことに気づくことができました。
しかし該当箇所を改善して実行してみると今度は「Debug Error! Program: ~~.exe abort() has been called (Press Retry to debug the application)」と出てしまいます。試しに似たような小コードを書いてみたのですが、やはり同じようなエラーが出るようです。原因を教えていただけると幸いです。
返信ありがとうございます。お陰様でtypeidの使い方が間違っていたことに気づくことができました。
しかし該当箇所を改善して実行してみると今度は「Debug Error! Program: ~~.exe abort() has been called (Press Retry to debug the application)」と出てしまいます。試しに似たような小コードを書いてみたのですが、やはり同じようなエラーが出るようです。原因を教えていただけると幸いです。
#include <iostream>
#include <memory>
#include <typeinfo>
using namespace std;
class Car {
public:
virtual void Display() = 0;
};
class RacingCar :public Car {
public:
void Display() override{
cout << "レーシングカーです"<<endl;
}
};
class PassengerCar :public Car {
public:
void Display() override{
cout << "乗用車です"<<endl;
}
};
int main() {
int id = 1;
unique_ptr<Car>car;
if (id == 1 && typeid(*car) != typeid(RacingCar))car.reset(new RacingCar);
if (id == 2 && typeid(*car) != typeid(PassengerCar))car.reset(new PassengerCar);
car.reset(new PassengerCar);
return 0;
}
- spaaaark・∀・
- 記事: 66
- 登録日時: 10年前
- 住所: 埼玉
- 連絡を取る:
Re: ループ内でのオブジェクトの動的確保について
このコードは、気を付けてくださいと言ったぬるぽを出しています((
if文の比較の際car変数が実体を指さないために、このコードは実行時エラーとなります。
対策は、例えば消し忘れたコードをif文の手前に持ってくるとコードは動作します。
(if文での比較前にcar変数にインスタンスを生成することがポイントです。)
恐らく現物の実装は常時実体があるわけではないと思うので、
宣言の際にcar(nullptr)と、スマートポインタをnullptrで初期化したうえで、
nullptrをif文でチェックしてから紹介した比較を行う必要があります。
なおこのとき、nullptrからインスタンスを作成する条件文は別途必要です。
if文の比較の際car変数が実体を指さないために、このコードは実行時エラーとなります。
対策は、例えば消し忘れたコードをif文の手前に持ってくるとコードは動作します。
(if文での比較前にcar変数にインスタンスを生成することがポイントです。)
恐らく現物の実装は常時実体があるわけではないと思うので、
宣言の際にcar(nullptr)と、スマートポインタをnullptrで初期化したうえで、
nullptrをif文でチェックしてから紹介した比較を行う必要があります。
なおこのとき、nullptrからインスタンスを作成する条件文は別途必要です。
クリエイティブな生活で刺激的な毎日を!