Home Segments Index Top Previous Next

746: Mainline

At this point, you have the essential machinery required for manipulating lists. It is time to see that machinery at work in a revised version of the analyze_train program. It makes a list of railroad cars, and then displays the usual report:

#include   
#include   
const double pi = 3.14159; 
// Box, cylinder, and railroad-car class definitions go here 
// Define list classes: 
class link { 
  public: 
    link *next_link_pointer; 
    railroad_car *element_pointer; 
    link (railroad_car *e, link *l) { 
      element_pointer = e; 
      next_link_pointer = l; 
    } 
}; 
class header { 
  public: 
    link *first_link_pointer; 
    link *current_link_pointer; 
    header ( ) { 
      first_link_pointer = NULL; 
      current_link_pointer = first_link_pointer; 
      } 
    void add (railroad_car *new_element) { 
      first_link_pointer = new link (new_element, first_link_pointer); 
      current_link_pointer = first_link_pointer; 
    } 
    void advance ( ) { 
      current_link_pointer = current_link_pointer -> next_link_pointer; 
    } 
    railroad_car* access ( ) { 
      return current_link_pointer -> element_pointer; 
    } 
    int endp ( ) { 
      return ! current_link_pointer; 
    } 
    void reset ( ) { 
      current_link_pointer = first_link_pointer; 
    } 
}; 
// Define list header: 
header train; 
char input_buffer[100]; 
enum {eng_code = 'E', box_code = 'B', tnk_code = 'T', cab_code = 'C'}; 
char extract_car_code (char *input_buffer) {return input_buffer[4];} 
main ( ) { 
  // No initialization or increment expressions: 
  for (; cin >> input_buffer;) 
    switch (extract_car_code (input_buffer)) { 
      case eng_code: train.add (new engine (input_buffer));   break; 
      case box_code: train.add (new box_car (input_buffer));  break; 
      case tnk_code: train.add (new tank_car (input_buffer)); break; 
      case cab_code: train.add (new caboose (input_buffer));  break; 
    } 
  train.reset ( ); 
  // No initialization; increment expression advances list: 
  for (; !train.endp ( ) ; train.advance ( ))  
    // Display number, short name, and capacity and terminate the line:  
    cout << train.access ( ) -> serial_number 
         << "     " 
         << train.access ( ) -> short_name ( ) 
         << "     " 
         << train.access ( ) -> capacity ( ) 
         << endl; 
} 
--- Data ---
TPW-E-783 
PPU-B-422 
NYC-B-988 
NYC-T-988 
TPW-C-271 
--- Result --- 
TPW-C-271     cab     0 
NYC-T-988     tnk     1539.38 
NYC-B-988     box     3990 
PPU-B-422     box     3990 
TPW-E-783     eng     0 

Note that the preceding program in Segment 746 will work fine without the instance of the reset member function placed just before the list-traversing for loop. Nevertheless, it is always a good idea to reset current_link_pointer before traversing a list, just in case some distant part of your function leaves current_link_pointer assigned inappropriately.