ページ 11

std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 16:45
by 夢幻ノ月夜
基底クラスのCObjectとEnemyExのデストラクタはvirtualにしてあるのですが、
どうやらEnemy_Kikibongoのデストラクタが呼ばれていないようなのです
ListはCObject*型になっています

コード:

class CObject{
protected:
	bool used;
	int obj_ID;
	float priority;
public:
	CObject(int ID,float priority=0.5f);
	virtual ~CObject(){}

	virtual void Move()=0;
	virtual void Draw()=0;

	bool operator <(const CObject *obj)const{
		return this->priority < obj->priority;
	}

	inline bool operator >(const CObject *obj)const{
		return this->priority > obj->priority;
	}

	float GetPriority(){
		return this->priority;
	}

	int GetID();

	friend bool Remove_Judge(const CObject *obj);
	friend bool Obj_Comp(const CObject *obj1,const CObject *obj2);
};

class EnemyEx :public CObject{
protected:
	int cnt;
	int HP;
	int MaxHP;
	float x, y;
	float a, sp;
public:
	EnemyEx(float x,float y,float a,float sp):CObject(O_ENEMY,0.3){
		this->x=x;
		this->y=y;
		this->a=a;
		this->sp=sp;
		this->cnt=0;
	};
	virtual ~EnemyEx(){}

	float GetX(){
		return this->x;
	}
	float GetY(){
		return this->y;
	}

	virtual void Damage(int value)=0;

	virtual void Move()=0;
	virtual void Draw()=0;
};

class Enemy_Kikibongo :public EnemyEx{
	int stop_time, restart_time;
	float Update_Angle;
	int state;
public:
	Enemy_Kikibongo(float x,float y,float a,float sp,int stop_time,int restart_time,float Update_Angle)
		:EnemyEx(x,y,a,sp){
			this->stop_time=stop_time;
			this->restart_time=restart_time;
			this->Update_Angle=Update_Angle;
			this->state=0;
			this->MaxHP=100;
			this->HP=100;
	}
	~Enemy_Kikibongo(){
		Score+=100;
		delete this;
	}

	void Damage(int value);

	void Move();
	void Draw();
};

void Object_Manager::MoveTask(){
	for(auto itr = List.begin(),end =List.end();itr!=end;itr++){
		(*itr)->Move();
	}
	List.remove_if(Remove_Judge);
}
Remove_JudgeにはCObject::usedがfalseだったらtrueを返す処理が書かれています
どうやったらデストラクタが呼ばれるようになるでしょうか…

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 17:12
by YuO
CObject *のデストラクタは呼ばれているはず (実際には組み込み型なので呼ばれないですが) です。

list<CObject *>はCObject *のリストであって,CObjectのリストではありません。
標準コンテナで継承関係を利用するには,事実上スマートポインタを用いて管理する必要があります。
# list<shared_ptr<CObject>>等。

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 17:14
by 夢幻ノ月夜
YuO さんが書きました:CObject *のデストラクタは呼ばれているはず (実際には組み込み型なので呼ばれないですが) です。

list<CObject *>はCObject *のリストであって,CObjectのリストではありません。
標準コンテナで継承関係を利用するには,事実上スマートポインタを用いて管理する必要があります。
# list<shared_ptr<CObject>>等。
CObjectのデストラクタがEnemyExのデストラクタを呼び出してくれることはないのでしょうか…

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 17:30
by YuO
夢幻ノ月夜 さんが書きました:CObjectのデストラクタがEnemyExのデストラクタを呼び出してくれることはないのでしょうか…
CObjectのデストラクタはいつ呼ばれるのでしょうか。
CObject*が破棄されるのであって,CObjectが破棄されるのではありません。

コード:

T ** ptr = new T *; // (a)
*ptr = new T; // (b)

delete ptr;
とやった時,(a)で生成したオブジェクト (T *型) は破棄されますが,(b)で生成したオブジェクト (T型) は破棄されません。
これとまったく同じことです。

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 17:32
by 夢幻ノ月夜
YuO さんが書きました:
夢幻ノ月夜 さんが書きました:CObjectのデストラクタがEnemyExのデストラクタを呼び出してくれることはないのでしょうか…
CObjectのデストラクタはいつ呼ばれるのでしょうか。
CObject*が破棄されるのであって,CObjectが破棄されるのではありません。

コード:

T ** ptr = new T *; // (a)
*ptr = new T; // (b)

delete ptr;
とやった時,(a)で生成したオブジェクト (T *型) は破棄されますが,(b)で生成したオブジェクト (T型) は破棄されません。
これとまったく同じことです。
じゃあどうしたらまともに動くでしょうか

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 18:02
by 夢幻ノ月夜
夢幻ノ月夜 さんが書きました:
YuO さんが書きました:
夢幻ノ月夜 さんが書きました:CObjectのデストラクタがEnemyExのデストラクタを呼び出してくれることはないのでしょうか…
CObjectのデストラクタはいつ呼ばれるのでしょうか。
CObject*が破棄されるのであって,CObjectが破棄されるのではありません。

コード:

T ** ptr = new T *; // (a)
*ptr = new T; // (b)

delete ptr;
とやった時,(a)で生成したオブジェクト (T *型) は破棄されますが,(b)で生成したオブジェクト (T型) は破棄されません。
これとまったく同じことです。
じゃあどうしたらまともに動くでしょうか
とりあえずshared_ptrを使ってみたいと思います

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 18:06
by 夢幻ノ月夜

コード:

void Weapon_NoWeapon::Move(float x,float y){
	std::shared_ptr<HPGauge> Hg=(std::shared_ptr<HPGauge>)Object_Manager::GetTask(O_GUAGE,0);
	if(Hg==NULL)return;
	Hg->SetHPGauge(this->HP*0.001f);
	Hg->SetSpecialGuage(0.0f);
}
次は要素を参照できなくなってしまいました
どうしたら派生クラスに変換できるでしょうか

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 18:14
by 夢幻ノ月夜
夢幻ノ月夜 さんが書きました:

コード:

void Weapon_NoWeapon::Move(float x,float y){
	std::shared_ptr<HPGauge> Hg=(std::shared_ptr<HPGauge>)Object_Manager::GetTask(O_GUAGE,0);
	if(Hg==NULL)return;
	Hg->SetHPGauge(this->HP*0.001f);
	Hg->SetSpecialGuage(0.0f);
}
次は要素を参照できなくなってしまいました
どうしたら派生クラスに変換できるでしょうか

コード:

std::shared_ptr<HPGauge> Hg=std::static_pointer_cast<HPGauge>(Object_Manager::GetTask(O_GUAGE,0));
これで出来たっぽいですかね?なんかこのままだとやばいことがあれば言ってください

Re: std::listのremove_ifにおけるデストラクタの呼び出しタイミング

Posted: 2016年5月05日(木) 18:30
by 夢幻ノ月夜
夢幻ノ月夜 さんが書きました:
夢幻ノ月夜 さんが書きました:

コード:

void Weapon_NoWeapon::Move(float x,float y){
	std::shared_ptr<HPGauge> Hg=(std::shared_ptr<HPGauge>)Object_Manager::GetTask(O_GUAGE,0);
	if(Hg==NULL)return;
	Hg->SetHPGauge(this->HP*0.001f);
	Hg->SetSpecialGuage(0.0f);
}
次は要素を参照できなくなってしまいました
どうしたら派生クラスに変換できるでしょうか

コード:

std::shared_ptr<HPGauge> Hg=std::static_pointer_cast<HPGauge>(Object_Manager::GetTask(O_GUAGE,0));
これで出来たっぽいですかね?なんかこのままだとやばいことがあれば言ってください
全部スマートポインタにしたら解決しました!
ありがとうございます!