Problem with a template class.

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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#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 &target;}

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.
Last edited on
Thanks a million, it's working perfectly now.

*tip of the hat.*
but thats not an iterator class..!!!

it doesnt have the basic functionality of an iterator class.
an iterator class is written something like this:
lets say we are making a link list:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
template<typename type>
class nlist
{
private:
	
	class nnode
	{
	private:	
	};

	nnode *_head;
	nnode *_last;

public:

	/**
		Iterator ***************
	*/
	class iterator
	{
	private:
		nnode *node;

	public:
		iterator(nnode *n) : node(n);
	

		iterator() : node(NULL);		
		~iterator();		

		iterator& operator++();		
		iterator& operator++(int);		
		bool operator !=(const iterator& iter);		
		bool operator ==(const iterator& iter);
		type& operator*();
	};

	
	/**
		nlist ********************
	*/
	//constructor
	
	//iterator support
	iterator begin();
	iterator end();
};
I guess that's why he said "iterator" and not iterator...it's sort of like an iterator, but it isn't one.
hmmm.. ok.. so for his next assignment he can implement a real one.. what say?? :D
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.
It is, but to be an "iterator" you must follow very specific requirements as set forth by the C++ standard.
http://www.cplusplus.com/reference/std/iterator/

It has a nice table showing you what each type of iterator can do.
Guys, it was just a test to experiment with templates =P

The iterator wasn't the point -- if he wanted a real iterator he would've used std::vector::iterator.
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.
I don't care either, I was just posting the information in case anyone wanted to know. XD
Topic archived. No new replies allowed.