operator ++/-- overloading in templates

Started by
9 comments, last by Jaiminho 16 years, 8 months ago
Hello fellas, I have implemented a linked list class using template and so far it's been working nicely. But now i added a feature that can iterate thru the items in the list and i used the operators ++ and -- to iterate from top-to-bottom and bottom-to-top of the list respectively. My implementation is shown below:

template < typename TYPE > 
class TLinkedList
{
private:
	// element structure with a pointer to its next/prev link (double linked list)
	struct Element 
	{ 
		TYPE Data; 
		Element* pNext; 
		Element* pPrev;
		Element( void ) { pNext = NULL; pPrev = NULL; } 
		virtual ~Element( void ) {} 
	};
	// pointer to the linked list's top/bottom element in the list
	Element* pHead;
	Element* pIterate;

public:
	TLinkedList( void );  // done 
	virtual ~TLinkedList( void ){ }  // done

	void	operator++( void ); // done
	void	operator++( int ); // done
	void	operator--( void ); // done
	void	operator--( int ); // done
};


template < typename TYPE >
void TLinkedList< TYPE >::operator++( void )
{ 
	if ( CanIterate() ) 
	{ 
		pIterate = pIterate->pNext; 
	}	
}


template < typename TYPE >
void TLinkedList< TYPE >::operator++( int )
{ 
	if ( CanIterate() ) 
	{ 
		pIterate = pIterate->pNext; 
	}	
}

template < typename TYPE >
void TLinkedList< TYPE >::operator -- ( void )
{
	if ( CanIterate() ) 
	{ 
		pIterate = pIterate->pPrev; 
	}	
}

template < typename TYPE >
void TLinkedList< TYPE >::operator -- ( int )
{
	if ( CanIterate() ) 
	{ 
		pIterate = pIterate->pPrev; 
	}	
}
If say i created a list for a type int: TLinkedList < int > i_list; calling i_list++ or i_list-- works just fine. However, if i now created a pointer to a list for type int: TLinkedList < int >* i_plist = new TLinkedList < int >; and call i_plist++ or i_plist--, my program crashes. I can see the problem here is that because i_plist is a pointer, the operator ++/-- tends to see i_plist as a pointer, and not a TLinkedList <int> causing it to perform its normal operation for pointers rather than the overloaded function defined in TLinkedList <int>. Is there any way to make the overloaded ++/-- operators be called even if i use those operators on pointers to list? Thanks in advance! Cheers! EDIT: Oh and btw, i'm by no means a c++ guru. So if you see any wierd or funny stuff in my code up there, feel free to bash at will. [Edited by - harmless on August 5, 2007 1:16:18 AM]
Advertisement
Ok it works now if i call:

(*i_plist)++ or (*i_plist)--;

However, the function doesn't seem intuitive now if i have to do it this way when handling a pointer to a list, therefore i would really love to find another approach to this problem.
Your list can only be iterated once at a time (you can't have two threads iterating the list, and you can't make a loop that would iterate the list from the beginning and from the end at the same time - the built-in iterator is only one). Personally, I think it is a lot bigger problem than having to add a few braces. Anyway, all this could be solved by creating another class - iterator class. Only this iterator should have ++/-- operators, and the list should never iterate over it self.
Your list has a fixed number of iterators (1), which doesn't seem nice. As already suggested, adding an iterator class solves this problem.

About the ++ and -- operators on the list, it can't be avoided on pointers, as it must always be acessed before doing anything with the pointed object. You can avoid this by getting a reference to the pointed type and, then, acessing it as a stack object.
Quote:Original post by Paulius Maruska
Your list can only be iterated once at a time (you can't have two threads iterating the list, and you can't make a loop that would iterate the list from the beginning and from the end at the same time - the built-in iterator is only one). Personally, I think it is a lot bigger problem than having to add a few braces. Anyway, all this could be solved by creating another class - iterator class. Only this iterator should have ++/-- operators, and the list should never iterate over it self.


hmmm.. i am a little confused.

What do you mean by saying i cannot have 2 threads iterating the list?
I don't think i am using a built-in iterator. in fact, i have incorporated a way to track the items in my list using a pointer member in the class. this pointer can move back and forth thru the elements in the list and a public method is available to do that. However, i am now trying to replace that public method with an operator. but if my list is a pointer, it doesn't seem to work.


Quote:Original post by Jaiminho
Your list has a fixed number of iterators (1), which doesn't seem nice. As already suggested, adding an iterator class solves this problem.

About the ++ and -- operators on the list, it can't be avoided on pointers, as it must always be acessed before doing anything with the pointed object. You can avoid this by getting a reference to the pointed type and, then, acessing it as a stack object.



ah yes, the idea of having more than one iterator is nice. I would love to implement an iterator class, is there any good links that you know of that i can reference to in order to implement one?

As for ++ and -- operators, i guess i'll just go back to using a function to iterate thru my list rather than using ++/--.

Thanks a lot for the reply.

Don't use (void) as the parameter list. That is a C throwback. In C++ you just write ().

Your postincrement and postdecrement have been implemented with the wrong behaviour. Look up the difference between preincrement and postincrement
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Hmm. There are obviously lots of problems here, but I'd like to address your original question with the correct answer:

It is impossible to get the behavior you asked for. The reason is that i_list is a list, so your operators are relevant. i_plist is NOT a list. It's a pointer to a list. Those are different types, with very different sizes, behaviors, legal operations, etc...

Have you worked with pointers much? Let's simplify the problem. Pretend that your list is actually just an integer (ie, a much simpler data type).

So you write the following code:

int a = 5;
cout << "Next number is: " << ( a + 1 ) << endl;

That should print 6, of course. What would you expect the following to print?

int *pA = new int;
*pA = 5;
cout << "Next number is: " << ( a + 1 ) << endl;

It's not going to print 6! (Unless your stack is arranged in a very odd way, but that would be a highly unlikely coincidence). The point is that pointers are their own type -- and all of the operators are already defined for pointers. In addition, even if it were somehow possible to break that behavior and use your own -- it would be disastrous.

Consider the following code:

TLinkedList< int > arrayOfLists[ 10 ];
TLinkedList< int > *pList;

for ( pList = arrayOfLists[0]; pList != arrayOfLists[10]; ++pList )
{
// Do things to pList!
}

This *should* be a legal way to use your list class. Any programmer that got your list could very easily end up writing code like this. Imagine his/her surprise when the ++ operator on their pointer (that they're using to iterate over the array) did something completely non-standard.
Or you could just, you know, use std::list.
... Indeed. That was going to be my next response, but I decided to give him the benefit of the doubt for now. If this is anything but a learning exercise, then you should immediately cease writing container classes. Step away from the keyboard and go think about a more interesting programming problem.

This topic is closed to new replies.

Advertisement