Thread: Keeping a Dynamic Object List and Referencing Them

  1. #1
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56

    Post [SOLVED] Keeping a Dynamic Object List and Referencing Them

    I searched the threads for help, but I'm not sure my terminology is correct. I'm a C++ hobbyist, and have a question about maintaining a list of objects, created dynamically at run time, and how to interact with those objects. I'd like to maybe use a vector, and some pointers, but I can't get it together. This is my first post.

    I've gotten it to work without the vector and list ideas where it just used 4 statically created class instances. I know it's a lot of code, but basically - all I want to do is maintain a vector of pointers (I think) to Monster objects created with new. I think. Any help is awesome, even a link to something or anything. I'm studying Accelerated C++ (Koenig, Moo) but it's complicated for me - the going is slow.

    Here's the class:
    Code:
    #ifndef MONSTER_H
    #define MONSTER_H
    
    #include <string>
    
    using namespace std;
    extern int monster_number;
    
    class Monster
    {
        public:
            Monster(string n = "Unknown", int hp = 500, int ap = 1000, int spd = 1000);
            virtual ~Monster();
            void report();
            string myname();
    
        private:
            string name;
            int max_health;
            int cur_health;
            int atk_pwr;
            int speed;
    };
    
    #endif // MONSTER_H
    Here's the class implementation:
    Code:
    #include "Monster.h"
    
    #include <iostream>
    
    using namespace std;
    
    Monster::Monster(string n, int hp, int ap, int spd)
    {
        monster_number++;
        cout << "Monster #" << monster_number << " Born!" << endl;
        name = n;
        max_health = hp;
        cur_health = hp;
        atk_pwr = ap;
        speed = spd;
        monster_pool.push_back(this);  // This fails horribly
    }
    
    Monster::~Monster()
    {
        cout << "Monster #" << monster_number << " Killed!" << endl;
        monster_number--;
    }
    
    void Monster::report()
    {
        cout << endl;
        cout << "Name: " << name << endl;
        cout << "    Hp: " << cur_health << "/" << max_health << endl;
        cout << "    Attack Power: " << atk_pwr << " Speed: " << speed << endl;
    }
    
    string Monster::myname()
    {
        return name;
    }
    And the main program:
    Code:
    #include <iostream>
    #include <vector>
    #include <cctype>
    
    #include "Monster.h"
    
    using namespace std;
    
    int monster_number = 0;
    
    vector<Monster> monster_pool;
    
    int main()
    {
        //vector<Monster> monster_pool;
    
        Monster Dragon( "Red Dragon", 5500, 450, 130 );
        Monster Goblin( "Goblin", 45, 65, 55 );
        Monster Orc( "Orc", 95, 135, 75 );
        Monster Worg( "Worg", 65, 125, 90 );
    
        //monster_pool.push_back(Goblin);
        //monster_pool.push_back(Orc);
        //monster_pool.push_back(Worg);
    
        bool Running = true;
        char choice = '?';
    
        while( Running )
        {
            cout << endl;
            cout << "Monster Menu" << endl;
            cout << "(S)pawn a monster" << endl;
            cout << "(K)ill a monster" << endl;
            cout << "(L)ist all monsters" << endl;
            cout << "(Q)uit" << endl;
            cout << "Choice? ";
            cin >> choice;
    
            switch( toupper( choice ) )
            {
                case 'S':
                    cout << endl;
                    cout << "Spawn Monster" << endl;
                    cout << "-------------" << endl;
                    cout << "(D)ragon" << endl;
                    cout << "(G)oblin" << endl;
                    cout << "(O)rc" << endl;
                    cout << "(W)org" << endl;
                    cout << "Spawn which type? ";
                    // cin >> choice;
                    // Monsters.spawn(choice);
                    //Monster *m+monster_number;
                    break;
                case 'K':
                    cout << endl;
                    cout << "Kill which monster?" << endl;
                    cout << "-------------------" << endl;
                    // Monsters.list();
                    cin >> choice;
                    // Monsters.kill(choice);
                    break;
                case 'L':
                    cout << endl;
                    cout << "Monster List:" << endl;
                    cout << "-------------" << endl;
                    // Monsters.list();
                    break;
                case 'Q':
                    Running = false;
                    break;
                default:
                    break;
            }
        }
    
        cout << endl << "Ending with " << monster_number << " monsters in the wild!" << endl;
        if( monster_number == 0 ) cout << "You killed all the monsters, hero." << endl;
        else cout << "I will slay them..." << endl << endl;
    
        return 0;
    }
    Last edited by M.Richard Tober; 05-29-2011 at 06:33 AM. Reason: Solved - but sadly can't change the title. :-/

  2. #2
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Have a look into smart pointers. Boost has a few really good ones, and they allow you to add dynamic objects to a std container (like a vector) and make sure the objects are destroyed when the container is emptied

  3. #3
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56
    I downloaded the boost library, and it's pretty complicated. Thank you for your swift response, I'll keep at it.

  4. #4
    Registered User Inanna's Avatar
    Join Date
    May 2011
    Posts
    69
    Here is an example of storing boost::shared_ptr in a vector.
    Code:
    #include <boost/array.hpp>
    #include <boost/shared_ptr.hpp>
    #include <stdlib.h>
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    class Monster
    {
        string m_name;
        int m_maxhp;
        int m_curhp;
        int m_ap;
        int m_speed;
    public:
        Monster(string name="Unknown", int hp=500, int ap=1000, int speed=1000)
            : m_name(name), m_maxhp(hp), m_curhp(hp), m_ap(ap), m_speed(speed) {}
        Monster(Monster const& orig)
            : m_name(orig.m_name), m_maxhp(orig.m_maxhp),
              m_curhp(orig.m_curhp), m_ap(orig.m_ap), m_speed(orig.m_speed) {}
        virtual ~Monster() {};
    
        string name() const { return m_name; }
    
        friend ostream& operator<<(ostream& os, Monster const& monster);
    };
    
    ostream& operator<<(ostream& os, Monster const& monster)
    {
        os << "Name: " << monster.m_name << endl;
        os << "    Hp: " << monster.m_curhp << "/" << monster.m_maxhp << endl;
        os << "    Attack Power: " << monster.m_ap << " Speed: " << monster.m_speed;
    
        return os;
    }
    
    int main()
    {
        typedef vector< boost::shared_ptr<Monster> > monster_pool_t;
    
        const boost::array<Monster, 4> available_monsters =
        {
            Monster("Red Dragon", 5500, 450, 130),
            Monster("Goblin", 45, 65, 55),
            Monster("Orc", 95, 135, 75),
            Monster("Worg", 65, 125, 90)
        };
    
        monster_pool_t pool;
        int n_monsters;
    
        cout << "Monsters to spawn: ";
    
        if (cin >> n_monsters)
        {
            for (int x = 0; x < n_monsters; ++x)
            {
                pool.push_back(boost::shared_ptr<Monster>(new Monster(available_monsters[rand() % 4])));
            }
    
            for (monster_pool_t::const_iterator x = pool.begin(); x != pool.end(); ++x)
            {
                cout << **x << endl;
            }
        }
    }

  5. #5
    C++ Enthusiast M.Richard Tober's Avatar
    Join Date
    May 2011
    Location
    Georgia
    Posts
    56

    Holy Moly. Thanks!

    You couldn't have had more than a half hour from my original post to format my mess of nonsense into a working (and elegant) solution. Well, thank you to Fordy for cluing my into the Boost library (I'm very excited about C-hex) and a special thanks to Ianna for... knocking the ball out of the park. lol Wow. I'm gonna be reviewing and studying that code for days (as soon as I stop having fun generating random numbers of monsters. =)

    Thanks again guys. I'll try to be more courageous with my explorations of Boost. SDL is the only library I really mess with up until now.

    M.R.T

  6. #6
    Registered User Inanna's Avatar
    Join Date
    May 2011
    Posts
    69
    You couldn't have had more than a half hour from my original post to format my mess of nonsense into a working (and elegant) solution.
    If it does what your code intended then I just got lucky. As an example the only goal was to randomly generate a list of dynamic monsters and print them out. As far as fleshing out the class hierarchy for an RPG battle system, there is still a lot of work to do.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. STL list and referencing
    By gautamn in forum C++ Programming
    Replies: 1
    Last Post: 06-13-2005, 12:40 AM
  2. Dynamic Creation of an object
    By axr0284 in forum Windows Programming
    Replies: 3
    Last Post: 02-05-2005, 10:27 AM
  3. dynamic object growth
    By Perspective in forum C++ Programming
    Replies: 5
    Last Post: 03-14-2003, 03:26 PM
  4. deleteing a dynamic object
    By Eber Kain in forum C++ Programming
    Replies: 4
    Last Post: 12-14-2002, 05:59 PM
  5. dynamic object initialisation??
    By splendid bob in forum C++ Programming
    Replies: 2
    Last Post: 07-04-2002, 12:35 PM

Tags for this Thread