Building a destructor that outputs data before destroying it

I am trying to build a destructor that takes an array pointer and outputs part of a private vector and, comparing a string within the objects, overwrites the data in the array with the data in the vector. (vector and array use same class type) It then proceeds as usual.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

///////////////////////////////
//       Declarations        //
///////////////////////////////
void banner (string name, string type = "\\", int size = 40);
class character{
public:
    character();                    // Constructor
    bool operator== (character);    // use when comparing init of objects
    bool operator< (character);
    bool operator> (character);
    string getname ()const ;        // return name of object
    string getname ();
    int getinit () const;           // return init of object
    int getinit ();
    void set_init (int a);          // set init of object to 'a'
    void heal_full();               // max out hp and 0 nl dam
    void heal(int amt);             // modify hp by given amount
    void heal_nl (int amt);         // heal nl dam by given amount
    void dam_nl (int amt);          // give nl dam by given amount, checks for disabled or unconscious state.
    int getHP();                  // return current hp
    int getnlDam();               // return nl dam

private:
    string name;            // name of character
    int mHP;                // max hit points
    int HP;                 // current hit points
    int nlDam;              // amount of non lethal damage object currently has.
    int init;               // initiative of character
};
class encounter{
public:
    encounter (character*, int);        // Constructor
    ~encounter (character*);
    void listFull ();
private:
    int ENEMIES;                        // number of enemies in this encounter
    vector<character> allpeople;        // vector of all people in encounter
    bool sortByInit (const character&,const character&) const;
};

1
2
3
4
int main() {
    character* player = new character[PLAYERS];
// ... Cut
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
encounter::encounter (character player_in[], int size ){
    banner ("NEW ENCOUNTER", "*");
    for (int i = 0; i < size; i++ ){
        allpeople.push_back(player_in[i] );
    }
    cout << "How many enemies?";
    cin >> ENEMIES;
    for (int i = 0; i < ENEMIES; i++ ){
        allpeople.push_back(character () );
    }
    cout << "Roll for initiative and input for each person or enemy:";
    for (unsigned int i = 0; i < allpeople.size (); i++){
        int in;
        cout << allpeople[i].getname() << ": ";
        cin >> in;
        allpeople[i].set_init(in);
    }
    using namespace std::placeholders ;
    sort (allpeople.begin(), allpeople.end(), std::bind( &encounter::sortByInit, this, _1, _2 ) );
}
encounter::~encounter (character*) {
    // ??? What should I put here to do what I outlined at the top?
}
bool encounter::sortByInit (const character& a,const character& b) const {
    if (a.getinit () == b.getinit ()) {
        int input = 0;
        while (input != 1 || input != 2) {
        cout<< a.getname() << " and " << b.getname() << " have the same initiative.\n"
            << "Please reroll and input who is higher.\n"
            << "1. " << a.getname() << "\n2. " << b.getname();
        cin >> input;

          switch (input) {
            case 1: { return true;}
            case 2: { return false;}
            default: {cout << "Invalid input please retry";}
          }
        }
    }
    else { return a.getinit() > b.getinit(); }
}
void encounter::listFull () {
    banner ("All Characters", ":");
    for (unsigned int i = 0; i < allpeople.size (); i++) {
        cout<< allpeople[i].getname () << " - HP: " << allpeople[i].getHP()
            << " - Initiative: " << allpeople[i].getinit ();
    }
}

I probably gave more then is needed to give suggestions... but better safe then sorry. If anyone wants to help please post at least a direction to move in as I am completely lost right now. I will be sleeping on the problem and checking back in the morning before trying to continue tackling the problem on my own. Thank you for giving me direction* that_way. :P
Last edited on
I think you need a new strategy, destructors can't take parameters :(
ok, could encounter:: have a pointer member that holds the address of the original array and is used in the destructor to "output" the players back to main ()? and how might I implement that... :/
If someone has a completely different take on this problem and wants to suggest a path to do so, let me know. :)
why not have a private variable be a character then assign it when you pass it through the constructor. Then on the destructor do what ever you need be with the varaible. Generally speaking though destructors are meant for freeing resources that may have been used.
Yes, destructors are deallocating the memory that the instance of the object was using. However, I want to save some of the data that this object used (the players current stats) and be able to continue using it after the object is destroyed and another instance is created (with different enemies to fight).

I have been looking at the different structures built into c++11 and I think that a modified forward list is what I want for this object, with an array input of players. The object takes the individual array members, and uses them in a list right where they are. This should negate the need to have a destructor try to output complete objects before deallocating them. The problem is that I am not sure how to try to create my own list other them to put a pointer into the character class that would theoretically point to the next lower init value for their turn. (There is also the added complexity of players holding their turns and jumping back into the action at a later point. but lets just get the basics figured out first.) If anyone could show me how I might modify what I have posted in the OP to create a custom list, and iterators that can:

1. Take the initiative from the user for each of the players and enemies/NPC's. (order not important here)
2. Sort the list by init spitting tied values back to the user to determine order of play.
3. Iterate through the list for normal operation.
4. (optional/secondary) Allow a "holding area" for people who want to hold their turn till later, able to jump back in at a moments notice.
5. Be able to identify whether all of the NPC's are dead and the encounter was survived.
6. Delete the NPC instances, but leave the player instances alone, able to go on another encounter, after ~encounter() is called.

I am thinking that this is probably going to need a lot of familiarity with pointers and pointer to pointers, which is not my strong point at this time. I do not expect, nor do I want someone to do it all for me, but I would like some mentorship/guidance if anyone is willing to take on the challenge. If you are willing please PM me.
Yes, destructors are deallocating the memory that the instance of the object was using. However, I want to save some of the data that this object used (the players current stats) and be able to continue using it after the object is destroyed and another instance is created (with different enemies to fight).


I feel like you're looking for a strategy to work around a flaw in your design, when a change in design would be more appropriate.

If the lifetime of the data should not be limited to the instance who's destructor is being called, then that instance should not own the data.

I might expect an "encounter" to own the mobs specific to the encounter, but I would not expect it to own a "character" that should exist outside the encounter.
Sorry about the delay, RL demanded my attention for the last couple days.

I might expect an "encounter" to own the mobs specific to the encounter, but I would not expect it to own a "character" that should exist outside the encounter.


So how would I pass in the character, so that the instance can modify it, without it "owning" it? The only thing that I can think of would be to have the character class contain pointers. The encounter instance would then contain an array of mobs and a linked list that bounces back and forth between the mob and player array in init order. This would allow the array of mobs that the instance builds to be destroyed at the end of the "encounter" while the players are still intact in main(). Could anyone point me to a tutorial that walks me through how to create and modify linked lists?

Thanks, Dnulho
Topic archived. No new replies allowed.