質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

解決済

HPゼロでオブジェクトを破棄する仕様を作りたいです

Spe3_0624
Spe3_0624

総合スコア3

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

2回答

0評価

0クリップ

429閲覧

投稿2021/12/22 08:11

前提・実現したいこと

C++でRPGじみた簡単なゲームを作りたいです。
そこでオブジェクト内のprivateメンバ変数(ここではHP)が0になったら、そのオブジェクトを破棄するという仕様を作りたいです。別クラスのオブジェクト内のメンバ関数(attack関数)でHPがゼロ以下になったらその関数内で、参照中のオブジェクトを破棄したいです。

今回はHPがゼロになる可能性のある関数に、オブジェクトを破棄する仕組みを加えるつもりですが、そもそもクラスの中に、メンバ変数が一定の条件を満たしたときに、オブジェクトを破棄する仕組みがあれば教えてほしいです。

該当のソースコード

言語はc++です
#include<iostream>

using namespace std;

class test{
int HP;
public:
test(int hp){cout <<"コンストラクタ"<<endl; HP = hp;}
~test(){cout <<"デストラクタ"<<endl;}
int getHP(){return HP;}
int setHP(int hp){HP = hp;}
};

class systems{
public:
void damage(int d, test &ob){
int hp;
hp = ob.getHP() - d;
ob.setHP(hp);

if(hp <= 0){ cout << d << " ダメージ受けた!!\n"; cout <<"HPがゼロになった\n"; /* ここで参照中のオブジェクトを破棄  */ }else{ cout << d << " ダメージ受けた!!\n"; } }

};

int main(){
test *t, t1(50);
systems s1;

t = &t1; s1.damage(20,*t); cout << t1.getHP() <<endl; s1.damage(30,*t); cout <<"終了\n"; return 0;

}

### 試したこと ob.~test()で直接デストラクタを呼び出してもうまくいきませんでした。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

BeatStar

2021/12/22 08:24

この手の場合は別のクラスオブジェクトが管理して、間接的にやるんじゃないかな。
fana

2021/12/22 08:27

> オブジェクトを破棄 する意義がわかりせん. (仮にそのmain()関数内で t1が唐突に解体されたとして,一体何がうれしいのですか?) オブジェクトを「破棄」することが何らかの意味を持つようなコード例を示すことはできませんか?
Spe3_0624

2021/12/22 08:34

testクラスに敵の情報の基を設定して、main関数内で敵を生成したいときに、testクラスを使って、仮引数(敵のHPなど)とともに敵を生成するという仕様で行こうと思ってました。そこで敵のHP(testのオブジェクト内のメンバ変数)が0になったら、そのままオブジェクトが残っていると気持ち悪いので、その時点で破棄したいと考えていました。 確かに今考えると、オブジェクトを破棄する場合は別のクラスなり関数なりを使用して破棄するのも手だと思いました。
fana

2021/12/22 08:45

何と言うか,オブジェクトが唐突に「破棄」されるのだとして,その「破棄」結果があなたのプログラムの動作(?)に何かしらの良い影響を与えてくれるような【仕組み】が無いと意味ないですよね. 【あるオブジェクトを「破棄」したならば,あれがこうなってここがああなるから,それによってこういう動作になってうれしい】みたいな. > オブジェクトが残っていると気持ち悪い とかじゃなくて.
Spe3_0624

2021/12/22 08:59

仕様としては、メンバ変数のHPがゼロになったら、デストラクタが起動して、「敵が倒れた」的な文とともに、次のステージに段階を進める操作を加えたいと考えていました。 仮にここでオブジェクトがそのままになっていた場合、main関数内に新たにHPが0になったかどうかを見極める関数を作らなければならず、その関数を使うタイミングなどが、プレイヤーからの操作によって実行手順が変わるプログラムにおいて少し不便だなと感じたので、HPが0になった時点でオブジェクトを処理する機能を加えたいです。 確かに現状のような小規模なプログラムでは別の方法でもなんとかなるかもしれませんが、ここからシステムを拡大していったときに支障が出ないとも言い切れません。
Serbonis

2021/12/22 09:25 編集

>オブジェクトを破棄 これは、1)オブジェクトのインスタンスを破棄する、2)オブジェクトを再利用できるようにする、のどちらを意図されているでしょうか?
Spe3_0624

2021/12/22 09:30

1)です。testクラスを基に敵(インスタンス)を生成し続け、そのインスタンス内のメンバ関数(HP)が0になり次第破棄するという仕様にしたいと考えています。
Serbonis

2021/12/22 09:58

まず、t1はmain関数を抜けるまで領域を占有しています。デストラクタを明示的に呼び出しでも、それは単にデストラクタというメンバ関数を呼び出すだけで、領域の解放とは直接関係がありません(main関数を抜けるときにもう1回呼ばれます)。1)の意図であれば、敵のインスタンスはnewで適宜動的に確保するのがよいかと思います。そしてインスタンスの破棄はインスタンス自身が行うのではなく、インスタンスを管理する別のクラス(ex.エネミーマネージャー)に行わせる方がよいかと思います。
fana

2021/12/23 01:16 編集

> testクラスを基に敵(インスタンス)を生成し続け (繰り返しになる感ですが) 刻々と生成なり破棄されていくインスタンス群をどうやって管理するのか? という話の想定がまず存在していないと,そもそも「破棄」の効能が不明瞭ですよね. ・生成とはどうやって行うのか? ・生成したからには以降でいつかそいつにアクセスしたくなるだろうけど,それはどうやってやるのか? ・破棄したからには以降はそいつにはアクセスしてはいけないのだろうけど,そのことはどうやって担保されるのか? ・etc... (例えば,既についている回答では std::vector<test> によって管理していますよね)

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。