This is for practice only; My knowledge of C++ is extremely limited and I'm wanting to expand. I want to make an "iterator" class that works with a vector to aid with using for loops. It looks something like this:
#include <iostream>
#include <string>
#include <vector>
template<typename T> class iter {
public:
iter(std::vector<T> vect);
~iter();
std::vector<T> *target;
int index;
void step();
T current();
bool iterating;
};
template<typename T>
iter<T>::iter(std::vector<T> vect){
*target = vect;
iterating = true;
index = 0;
}
template<typename T>
iter<T>::~iter(){delete ⌖}
template<typename T>
void iter<T>::step(){
index++;
int size = target->size();
if (index >= size) {
iterating = false;
}
}
template<typename T>
T iter<T>::current(){
return target->at(index);
} // END CLASS TEMPLATE "iter."
It's intended to be used in the following fashion:
1 2 3 4 5
vector<type> newVector;
<... add to newVector>
for ( iter<type> i(newVector); i.iterating; i.step() ){
std::cout << i.current() << '\n';
}
That is supposed to send each entry in "newVector" to the out stream. When I run it (on Windows Vista, AMD Athlon x86) I get a crash. I tried passing "newVector" as a reference, and I got fairly strange output; for some reason, I saw operating system information and undisplayable characters.
I'm assuming this has something to do with my pointers, but I'm not sure.
Don't delete something unless you allocated it with new. Your iterator class does not "assume ownership" of the vector, and as such should not delete it in its dtor.
Other than that... there are two problems with your pointer assignment:
1 2 3 4 5 6 7 8 9 10 11
*target = vect; // VERY BAD
/*
this creates a whole copy of the vector to whatever 'target' points to...
which... since you never set it to point to anything, is corrupting RAM
*/
target = &vect; // good
/*
sets your 'target' pointer to point the 'vect' vector
*/
However there's yet another problem:
1 2 3 4 5 6 7 8 9 10 11
iter(std::vector<T> vect); // BAD
/*
creates a copy of the vector (passed by value). this will result in your pointer pointing to a temporary
object... and when that object dies (which will be as soon as the ctor exits -- ie: practially
immediately) your pointer will be bad, and accessing it will have terrible consequences
the solution here is to pass by reference:
*/
iter(const std::vector<T>& vect); // GOOD
make those changes and get rid of the delete and see if it works after that.
EDIT: added pass-by-ref stuff (missed it first time around)
EDIT again: blah -- of course if your reference is const you'd also have to make your pointer const. So either do that or don't make the reference const.
Firedraco nailed it; I just said "iterator" for lack of a better word. I actually made it to simi-emulate Python for loops. To be honest though, I'm not sure what the exact definition of a true iterator is. I -thought- that they were something that continually returns the next item in a series each time it is called. For example, if I made my class call "step" inside of "current." Each time current is called, it returns the current value and takes a step.
I'll google it later though; thanks for the heads up.
What he has written is an application of the iterator pattern, which does not necessarily mean that it has to conform to the interface provided by the STL iterators. In a more general context, I see nothing wrong with referring to it as an iterator. I do agree that conforming to the widely accepted iterator interface is advantageous, though.