Quote:Original post by c4c0d3m0n
What's the difference between boost::array, a normal C++ array or a Vector?
Normal C++ arrays are, well, the horrible beasts you have been reading about.
boost::array is a class that provides the same basic interface as an array (i.e. you can get and set elements by using [index]es), but the convenience of working with an actual object (because you actually have one). That is, you can treat the type name (boost::array<elementtype, count>) the same way you treat 'int' or 'double', so specifying a reference to one is much more straightforward (it looks the same as specifying a reference to an int or double), and you never have to worry about weird things like pointer decay.
It's actually very easy to get the same effect by writing it yourself: basically, all they do is make a class which has an array of the appropriate type and size as a data member (this is where templating comes in - so that the one template can be instantiated for any kind of array you may need), and give it overloads for 'operator[]' which delegate to the array.
std::vector, although it's in the standard library rather than the third-party Boost libraries, provides a rather more complex behaviour. It's designed to behave like a *resizable* array. It does this by keeping a dynamic array-allocation on the heap somewhere, and remembering the size of its allocation (the 'capacity'), as well as the amount of that allocation that is actually in use (the 'size'). You can explicitly resize to a larger amount (causing the remaining slots to be filled in with default-constructed values) or implicitly by appending things to the end (with '.push_back()'), and if the size is about to exceed the capacity, the vector will automatically allocate a bigger chunk, copy all the elements over, put in the requested new elements, and then clean up the old chunk. It also cleans up its current memory chunk in the destructor, and does similar things in the copy constructor and assignment operator. The net effect is that you can use the vector
as if the array elements were all just on the stack (rather than being in a dynamic allocation); the vector does all the "memory management" for you.
As you can imagine, implementing this one properly is considerably more involved. There's also no reason to, since the standard library already provides it.
Quote:Quote:Passing a pointer IS NOT passing by reference. C++ has real references; use them.
What is the difference? How do I do the latter? I have no experience in references nor pointers, I was just experimenting.
References.Out of curiousity, though, if you *don't* know any of this, then where did you find the term "reference" at all?
Quote:When I compile, I get an error that boost hasn't been declared.
Well, of course. The Boost libraries are third-party; they don't come with your compiler - you need to download some headers, and in some cases (not for boost::array though), do some installation work (i.e. compile some implementation files).
(Although, as mentioned before, it's really not that hard to do yourself:
template <typename T, size_t size>class array { T storage[size]; public: const T& operator[](size_t pos) const { return storage[pos]; } T& operator[](size_t pos) { return storage[pos]; }};
If any of that doesn't make sense, see
here.
And IIRC, boost::array *does* do a few other things besides that, but they're probably not things you'll desperately need.)
Quote:All the following errors have to do with the iMatches() function.
Don't pass a single cell to it; pass a field.
Anyway, just wanted to comment on this monstrousity:
switch( field[j].jewel * field[j].used ) { case 0 : if( field[j].used ) { applySurface( offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, bluej, screen ); } break; case 1 : applySurface( offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, greenj, screen ); break; case 2 : applySurface( offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, orangej, screen ); break; case 3 : applySurface( offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, purplej, screen ); break; case 4 : applySurface( offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, redj, screen ); break; case 5 : applySurface( offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, silverj, screen ); break; case 6 : applySurface( offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, yellowj, screen ); break; }
We're using tricky arithmetic (multiplying by a boolean? o_O) that actually doesn't help us out (because we *still* have to handle a special case if the result is 0), and duplicating code (the only thing that changes is which jewel to use).
The natural way of letting a number specify which jewel image to use would be to put the jewel images into an array, and let the number index into the array:
// And again, a reference can help us...cell& c = field[j];if (c.used) { applySurface(offset.x, offset.y, SQUARE_SIZE, SQUARE_SIZE, jewels[c.jewel], screen);}