Dynamic Array Woes
Fairly new to C++ and want to make an Array that I can add new elements, take some away, rearrange the order and such. With some tutorials I have read, none seem to be able to explain how I do this though. I have an inkling that these are properties of another concept (vector, map?)
Tar
Questions:
1) Does the data have to be in a contiguous memory block?
2) From where do you want to remove elements? (Front, back or anywhere?)
1) Does the data have to be in a contiguous memory block?
2) From where do you want to remove elements? (Front, back or anywhere?)
Quote:Original post by ConorH
Fairly new to C++ and want to make an Array that I can add new elements, take some away, rearrange the order and such. With some tutorials I have read, none seem to be able to explain how I do this though. I have an inkling that these are properties of another concept (vector, map?)
Tar
Arrays are usually static in size - that is, once you create the array, it stays at the size that you created it. It is possible to flag items in the array as in-use or not, but technically, they are still there. You probably want to look into something called a linked list. A linked list will allow you to add and remove items in the list, as well as reorder them.
A std::vector or std::list is probably what you want. Check out these FAQs as well for pertinent information and some more details.
Im using my vector/list to store SDL_Surface* but when I try and return the reference for it, it gives me an error
std::list<SDL_Surface*> im;
int cSprite::LoadImage(const char* _file)
{
//Add the loaded file onto vector list
im.push_back(Gfx.LoadImage(_file));
return im.end();
}
1>.\engine.cpp(111) : error C2440: 'return' : cannot convert from 'std::list<_Ty>::_Iterator<_Secure_validation>' to 'int'
1> with
1> [
1> _Ty=SDL_Surface *,
1> _Secure_validation=true
1> ]
I want to be able to get the reference from the function though :(
Any ideas? I can see that Im doing something wrong here
edit: I assume that references arent in the form of int's then. Im used to referencing array elements with ints/int literals from when I used DarkBasic
std::list<SDL_Surface*> im;
int cSprite::LoadImage(const char* _file)
{
//Add the loaded file onto vector list
im.push_back(Gfx.LoadImage(_file));
return im.end();
}
1>.\engine.cpp(111) : error C2440: 'return' : cannot convert from 'std::list<_Ty>::_Iterator<_Secure_validation>' to 'int'
1> with
1> [
1> _Ty=SDL_Surface *,
1> _Secure_validation=true
1> ]
I want to be able to get the reference from the function though :(
Any ideas? I can see that Im doing something wrong here
edit: I assume that references arent in the form of int's then. Im used to referencing array elements with ints/int literals from when I used DarkBasic
Quote:Original post by ConorHTwo problems are immediately evident here:
std::list<SDL_Surface*> im;
int cSprite::LoadImage(const char* _file)
{
//Add the loaded file onto vector list
im.push_back(Gfx.LoadImage(_file));
return im.end();
}
1. list::end() returns an iterator that points 'one past the end' of the list. It appears you want to access the last item added to the list; to do so, use list::back().
2. The function return type is int, but you're trying to return an SDL_Surface*.
I recommend fixing these errors and then re-posting your code (as there are some other areas where improvements could be made).
If list::end()/back() returns an iterator for the last element, how come its returning the value of it (SDL_Surface*)?
Im trying to abstract the use of SDL_Surfaces, and just use image numbers for instance, so that's why I want to return the iterator
Im trying to abstract the use of SDL_Surfaces, and just use image numbers for instance, so that's why I want to return the iterator
Quote:Original post by ConorH
If list::end()/back() returns an iterator for the last element, how come its returning the value of it (SDL_Surface*)?
list::end() returns an iterator that is after the last valid iterator. It doesn't have an associated value and should not be dereferenced. If the iterator is bidirectional (it is, for a list), you may decrement a copy of end() to reach the last element.
list::back() returns a reference to the last element: it's neither an iterator nor a value.
Either way, an iterator is not an integer, so a function which has an int return type should not and cannot return an iterator.
EDIT: an alternative:
// Use integers as identifiers. They are recycled.template<typename T>class IDMap{ std::vector<T*> elements; std::vector<int> free_indices;public: T& operator[](int i) { assert (i >= 0); assert (i < elements.size()); assert (elements); return *elements; } int add(T& element) { if (free_indices.empty()) { elements.push_back(&element); return elements.size() - 1; } else { int index = free_indices.back(); free_indices.pop_back(); elements[index] = &element; return index; } } void remove(int index) { assert (i >= 0); assert (i < elements.size()); assert (elements); elements[index] = 0; free_indices.push_back(index); }};
This object is responsible for translating indices into object pointers and vice versa, and may be used as part of a greater system which only lets the indices be public.
Of course, wrapping the texture in an object would be a much better way of abstracting this.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement