You are here:

C++/test program

Advertisement


Question
QUESTION: it's me again :)
could you also please help me to come up with a test for operator++ and operator++(int)?
I understand the difference between the prefix and postfix but don't know how to test them!
I also don't understand why in the for loops we use:
for ( ; ; ++it)
and not( ; ;it++)

also if your time allows and if it's not too many questions in one email, could you take a look at my test, the last for loop does not print list3, I don't see what is wrong!
http://rafb.net/p/OtQzKc68.html
thanks for your time :)

ANSWER: > I understand the difference between the prefix and postfix but don't know how to test them!

there is no difference between the prefix and postfix increment/decrement operators with respect to what happens to the object.

int x = 100 ;
x++ ; // x is incremented, it is now 101
x = 100 ;
++x ; // x is incremented, it is now 101

the difference occurs when you use the result of the increment/decrement in an expression.

int x = 100 ;
int y ;
y = x++ ; // y gets the old value of x, y is now 100. x is incremented, x is now 101
x = 100 ;
y = ++x ; // x is incremented, it is now 101. y gets the incremented value of x, y is now 101.

in particular, prefix increment returns a reference to the object that was incremented.
postfix increment returns an anonymous temporary that holds the value of the object before it was incremented.

to get this behaviour, modify as follows:

template <typename T>
class List {
 public:
   // ...
   class Iterator {
     // ...
   public:
     // ...
     Iterator operator++(int junk);
     Iterator& operator++();
   };//end of class Iterator

}; // end of class List

template <typename T>
typename List<T>::Iterator List<T>::Iterator::operator ++(int junk) {
 //post increment
 Iterator previous_value = *this ;
 this->position = this->position->next;
 return previous_value ;
}

template <typename T>
typename List<T>::Iterator& List<T>::Iterator::operator ++() {
 //pre increment
 this->position = this->position->next;
 return *this ;
}


and now it is easy to test the operators:

List<string> personnel;

personnel.add("first");
personnel.add("second");
personnel.add("third ");
personnel.add("forth");
personnel.add("fifth");
personnel.add("sixth");

List<string>::Iterator a = personnel.getFirst();
List<string>::Iterator b = ++a ; // both a and b should now 'point' to "second"
std::cout << "a => " << *a << "  b => " << *b << '\n' ;
List<string>::Iterator c = b++ ; // now c should 'point' to "second", b to "third"
std::cout << "c => " << *c << "  b => " << *b << '\n' ;


> I also don't understand why in the for loops we use: for ( ; ; ++it) and not( ; ;it++)

with the above explanation, this should be easy to see:
it++ requires the creation (and destruction) of an anonymous temporary.
++it does not; it is therefore more efficient.

> the last for loop does not print list3, I don't see what is wrong!
there is a subtle error in your List<T>::remove. when the number of elements in the list is exactly one, remove removes the element which is both the first and the last element. this needs to be handled as a special case.

template <typename T>
void List<T>::remove(Iterator& pos) {
 /*
 1: find the position of the element using the pos Iterator
 2: manipulate the links so that the element leaves the list
 3: delete the memory allocated to that element
 */


 if(lastElement==NULL && firstElement==NULL) {
   //list is empty, nothing to remove
   return;
 } else {
   //list is not empety
   if(pos.position == NULL) {
   /*
     the pos Iterator points at the end of the list
     so there is nothing to remove.
     *** this code is just to show that we consider all possible conditions ***
   */
     return;


   } else if(pos.position == firstElement){
     /*
     the pos Iterator points to the first element of the list
     so we are removing the first element of the list
     */

       if( firstElement == lastElement ) // the only element is removed
       {
         // remove the only (first and last) element
         firstElement = 0 ;
         lastElement = 0 ;
         // the list is now empty
       }
       else // there are more than one elements in the list
       {
         // first element is removed
         firstElement = firstElement->next;
         // last remains unchanged
       }
   } else {
     /*
     the pos Iterator points to somewhere in the middle of the list
     so we are removing an element from the middle of the list
     */

     pos.position->prev->next = pos.position->next;
     pos.position->next->prev = pos.position->prev;
   }
   /*
     delete the memory allocated to the element
   */
   delete pos.position;
 }
}

you might want to have a look at this: http://www.learncpp.com/cpp-tutorial/97-overloading-the-increment-and-decrement-


---------- FOLLOW-UP ----------

QUESTION: thank you so much for your prompt answer as usual :)

is "firstElement = 0 ; " same as "firstElement = NULL ; "?
also there seems to be an error still with the operator++ with the modified code. please see the link below
http://rafb.net/p/IlvTJl90.html

ANSWER: > is "firstElement = 0 ; " same as "firstElement = NULL ; "?

yes, in C++ the definition of NULL is 0. there is only an aesthetic difference between the two.

i prefer not to use the NULL macro, it has no advantage over 0. eg.
int* ptr = NULL ; // ptr is a null pointer, it does not point
int value = NULL ; // value is zero

in C++09 "nullptr" will be a keyword and we could also write

firstElement = nullptr ;

which perhaps documents the intent better.

> there seems to be an error still with the operator++ with the modified code

i could not see any obvious error. what exactly is the error that you have encountered?



---------- FOLLOW-UP ----------

QUESTION: thanks for your answer.
are there any side effects of having everything in .h file in my case( list.h) or in general?

Below I pasted the test program with the error
http://rafb.net/p/vx4jiH31.html

and here is the list.h file:
http://rafb.net/p/phlIo837.html

Answer
> are there any side effects of having everything in .h file in my case( list.h) or in general?

in general, having everything in a .h file would not be a very good idea.

a. whenever a .h file changes, all .cpp file which #include it would have to be recompiled. if all the implementation is in a .h file, whenever the implementation changes, any other file which #includes this file would require recompilation. this increases the compile-time coupling.

b. as a header can be included as a part of many translation units (simply by #including it), any variable or function defined in the header must have internal linkage ie. it would have one copy per translation unit. this can increase the memory footprint of the program.

templates are a special case:

a. the compiler needs to see template definitions at compile time.
b. the instantiated templates have to be regenerated whenever there is a change to any part of it. this requires a recompilation of all users of the template.
c. template definitions by default have internal linkage.

template definitions are needed in every file that uses them, so we put them in a header which is included in any place where we want to use it.   

> Below I pasted the test program with the error

i copied your code (List.h and test.cpp) and got no error except a warning here:

/****************************************************

         Class ELEMENT

//***************************************************/
warning: "/*" within comment

and running it seemed to give the expected results.  

it looks like you are including an older version of List.h in test.cpp.

hint: make sure that the current (latest) version of these two files are in the same directory.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.