I am trying to write a short RPG like program to teach myself C++. I would only like the program to allow the user to by items (sword, shield, etc.) from a store and add them to their list of items. I'd also like for these items to be objects of a class so that I can give them data members such as name and price. But I can't figure out how to put objects into something like a vector or an array. Is there a way to do that? Or is there some other way?

Recommended Answers

All 2 Replies

You want the user to be able to buy items. (You accidentally misspelled that.)

Your best bet is to use one of the STL collection classes with a base item type.

That is, create an abstract class for your items, and derive specific items from it. Then use something like std::set to store the items.

Hope this helps. If you get stuck post again.

I ran into a similar situation as yours, so I'll tell you what difficulties I encountered and how I chose to deal with them. I'm still learning though, same as yourself, so you're better off asking one of the gurus here..

Anyway, any sort of array or STL container is restricted to storing things of the same size as far as I understand. In practice this means storing things of the same type. i.e. you can have a std::vector<CSword> or std::deque<CShield>. But what you really want is to store them all in the same container, for convenience.

Well with polymorphism you can create a container of base class pointers and have those pointers point to appropriate derived classes if you wish. This seems ideal because for example you can do something like:

#include <iostream>
using namespace std;

class CItem
{
public:
      virtual void Use() { cout << "using item\n"; }
};

class CSword : public CItem
{
public:
      void Use() { cout << "using sword\n"; }
};

class CShield : public CItem
{
public:
      void Use() { cout << "using shield\n"; }
};

int main()
{
    int numItems (2);
    CItem** items = new CItem*[numItems];
  
    items[0] = new CSword;
    items[1] = new CShield;
    
    items[0]->Use();
    items[1]->Use();
  
    return 0;
}

Or alternatively you can use an STL container such a map to easily identify the items by name.

However the limitations of this are that you are restricted to calling base class functions.
So consider the following modification:

#include <iostream>
using namespace std;

class CItem
{
public:
      virtual void Use() { cout << "using item\n"; }
};

class CSword : public CItem
{
public:
      void Use() { cout << "using sword\n"; }
      void Attack() { cout << "swoosh...\n"; }
};

class CShield : public CItem
{
public:
      void Use() { cout << "using shield\n"; }
};

int main()
{
    int numItems (2);
    CItem** items = new CItem*[numItems];
  
    items[0] = new CSword;
    items[1] = new CShield;
    
    // This is ok because they're polymorphic calls
    items[0]->Use();
    items[1]->Use();

    // This will give an error
    items[0]->Attack();
  
    return 0;
}

So you may not use any of the derived class' special abilities as it were, unless they are polymorphic variants of a defined base class function.
This means that either you are restricted in that you either have to constantly update your base class (bad OOP) or you have to limit your use of the objects in the containers (kind of useless in this context).

So what I ended up doing instead was making a bunch of containers of each item type and something like a CItemManager class which managed this overall item collection.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.