Sign in to follow this  

operator ++/-- overloading in templates

This topic is 3780 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
... 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.

Share this post


Link to post
Share on other sites
Quote:
Original post by harmless
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?

Iterators classes are simply wrapped pointers. You have a pointer to your element (in this case, the list node) which is set to point to this->pNext and this->pPrev with the operators ++ and --. Aside from that, you need operators to compare (basically, only == and !=) the used iterator with one returned by a list method and an access operator to retrieve the data contents of the node, usually with unary operator * (you don't return a reference to the node, but a reference to the data). Of course, there are lots of complications and improvements done on std::list, but the basic is simply that.

You can google for the interface on std::list to check how it actually works. Anyway...

Quote:
Original post by osmanb
Step away from the keyboard and go think about a more interesting programming problem.


Yes, it is a quite too simple programming problem.

Share this post


Link to post
Share on other sites

This topic is 3780 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this