2

After searching google and stackoverflow for 2 days I haven't found anything yet

I was working with java about a year now and I decided to create a game on C++ for practice

In java this should work but in C++ it blows my mind.

I have this code

Item* inventory = new Item[24];

It's array (inventory) that holds Items

When I allocate dynamicly an array all of its postions are null? And if not, can I make them all null?

And thats the code for add an item at first empty position (pick up an item)

void Inventory::addItem(Item it){
    if(isFull()){
        cout << "Full inventory" << endl;
    }else{
        for(int i = 0; i<length; i++){
            if(inventory[i] == nullptr){ // need this to work somehow
                  inventory[i] = it;
            }
        }
    }
}

It needs to be array not a vector because it has fixed size

1
  • exactly what is the error? The way you declared your array, the line inventory[i] = it should be the one throwing an error. Commented Jan 21, 2014 at 16:25

2 Answers 2

6

When I allocate dynamicly an array all of its postions are null? And if not, can I make them all null?

There's no such a thing as a null object in C++, like there is in Java. You can have a nullptr pointer, instead. In your case the objects are default constructed, and are therefore not null.

It needs to be array not a vector because it has fixed size

You generally do not want to dynamically allocate unless it is strictly necessary. Use an std::array, if you really want a fixed sized array.

What I would suggest is to use an std::array in combination with an std::unique_ptr:

std::array<std::unique_ptr<Item>, 24> arr;

By default, all std::unique_ptrs will be nullptr. When you'll need to allocate an object you will able to do:

arr[i] = std::unique_ptr<Item>(new Item(...));

You can even create an alias for the smart pointer:

using item_ptr = std::unique_ptr<Item>;

that will help you rewrite your code as:

std::array<item_ptr, 24> arr;
arr[0] = item_ptr(new Item(...));

Alternatively you can also use boost::optional (or std::optional from C++14):

std::array<std::optional<Item>> arr;

You will be able to check if a specific i element is "null" (in the Java sense) with:

if (arr[i])
    // not null

and you'll be able to assign a value with:

arr[i] = Item(...);

and retrieve it with *arr[i], arr[i]->member_function(...); or arr[i]->member_object.

Sign up to request clarification or add additional context in comments.

2 Comments

one question, do I have to deallocate or delete this unique_ptr?
@LittleJacod, nope. That's the whole point of the class: to automate the deletions of the resource.
2

Contrary to your final comment, this seems to be a perfectly reasonable application for std::vector.

As it stands right now, you're trying to create an array of N objects, but then have some M of those actually be null/empty/nonexistent objects.

The reality is that this is not a fixed size collection at all. It's a variable sized collection up to some specified maximum. At a given time a player might be carrying 1 item or 10, but there's some maximum number of items they can carry. They're not, however, constantly carrying the maximum number of items, and some of those happen to be null items1.

Since what you're dealing with really is a variable sized collection (up to a specified maximum), std::vector fits the bill perfectly. Since you're dealing with an Item class, it's probably reasonable to assume that the actual items will be instances of concrete classes that derive from Item. That being the case, you really need to store (some variety of) pointer in the array, not actual Item objects (Otherwise, every derived item you try to put into the array will be "sliced" to become an actual Item object, not a derived object, when it's stored in the array).

You can do that by creating a collection of unique_ptrs (or various other other smart pointer types, such as shared_ptr), but I'd generally recommend that in such a situation you consider the Boost ptr_vector type instead.

As far as enforcing the size limit goes, you probably want to create a small wrapper class to handle this. It's not exactly a complex task, but it's clearly better to centralize that code in one place, not duplicate the size checking code everywhere you might add an item to an inventory.

template <class T>
class inventory { 
    ptr_vector<T *> items;
    size_t max;
public:
    inventory(size_t max) : max(max) {}
    push_back(T *t) { 
        if (items.size() < max)
            items.push_back(t);
    }

    // other miscellany here.
};

It's possible, however, that you don't have a polymorphic hierarchy of Items. Instead, you have just have a single, fixed type for all items in the inventory, each of which has a name and such. If that's the case (i.e., all Items are really the same type of object), there's no reason to mess with pointers or ptr_vector. You really just want a std::vector<Item>. Much like above, however, you undoubtedly still want to centralize the code to enforce the Inventory's maximum size (and probably provide other inventory-specific services as well).


  1. If you'll allow me a digression, the fact that somebody would even consider such a possibility indicates the degree to which using Java warps people's minds and destroys their ability to think clearly. To paraphrase Dijkstra, teaching Java should be a criminal offense.

7 Comments

It is to notice that with this method you won't be able to have alternated "null objects" (in the Java sense, let's not be pedantic) and valid objects.
I'm not too sure about vector being so obvious here. Simply thinking about RPG games, it's always nice to be able to organize a player's inventory, like this: media.indiedb.com/images/games/1/17/16438/inventory.png. This obviously means that items need an index to position them in a given slot. The vector solution would not allow for empty slots, unless by swapping around special "empty" items.
First of all thanks for you answer it didn't just helped me it TOUGHT me 2 or more things, and yes i used a polymorphic hierarchy for items. Just i want comment your last digreesion. I'm a student at my second year at university and we are using java for introduction to programming, for the reason that we are inexperience with memory and memory management and C++ is very hard for our current knowledge. You are probably a programmer with 20 years expirerience but for me it is REALLY hard to understand all this concept, and thats why i started working alone
@JerryCoffin, I can't see how they are "hideous messes", and they are often useful in certain applications.
because i want to understand the whole thing. And java is really good for introduction to programming
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.