Question: The bag class that we have been working with currently has no way to iterate and output the items in the container. C++ has a

The bag class that we have been working with currently has no way to iterate and output the items in the container.

C++ has a way to define custom iterators for a container class. However, it is tedious since you typically have to implement support for a forward iterator, const forward iterator, reverse iterator, const reverse iterator, random iterator, and const random iterator. In this lab we will create only a forward iterator to work with the bag class. Since bag is only a singly linked list, the only other iterator that would makse sense to add is the const forward iterator.

Create new a file bagi.h and create a new derived class with bag as the base class. Do not bother creating a bagi.cpp file, since all the items you will need to add to the new class can be done inline. In addition, this gets us ready to how life will be with tempaltes.

Add the following to bagi.h:

#ifndef BAGI_H_ #define BAGI_H_ #include "node_iterator.h" #include "bag3.h" namespace bagiter { //Extend the bag class by adding an iterator class bagi: public bag { public: typedef node_iterator iterator; //Overrides if any required //Will need to implement begin() and end() member functions here //They will return an iterator, which is a new class (node_iterator) //you need to create //The member functions will return iterator(/*value in here*/) }; } /* namespace bagiter */ #endif /* BAGI_H_ */

Create a new file node_iterator.h and add the following and implement each function:

#ifndef NODE_ITERATOR_H_ #define NODE_ITERATOR_H_ #include  // Provides iterator and forward_iterator_tag #include "node1.h" namespace bagiter { class node_iterator : public std::iterator { public: node_iterator(node * initial = nullptr) { //Constructor } node::value_type& operator *( ) const { //should give the the value the iterator points to } node_iterator& operator ++( ) // Prefix ++ { //Move to the next node  } node_iterator operator ++(int) // Postfix ++ { //Move to the next node, however, return a copy of what the old node } bool operator ==(const node_iterator other) const { //Pointing at SAME NODE? } bool operator !=(const node_iterator other) const { //Not ointing at SAME NODE? } private: node * current; }; } #endif 

____________________________________

#include

#include "bagi.h"

using namespace std;

using namespace bagiter;

//For testing of the expected results, for now just see the magic, we will create a template next week

template

void resultOut(const char*, T, T);

int main() {

bagi b1;

node_iterator iter1;;

node_iterator iter2;

b1.insert(5);

b1.insert(15);

b1.insert(30);

bagi b2(b1);

b2.insert(45);

for ( node_iterator it = b1.begin() ; it != b1.end() ; ++it) {

cout << *it << endl;

}

for ( node_iterator it = b2.begin() ; it != b2.end() ; ++it) {

cout << *it << endl;

}

iter1 = b1.begin();

iter2 = b2.begin();

resultOut("Iterator *", *iter1, 30.0);

resultOut("Iterator ==", iter1 == iter2, false);

resultOut("Iterator !=", iter1 != iter2, true);

iter1 = b1.begin();

iter2 = b1.begin();

resultOut("Iterator ==", iter1 == iter2, true);

resultOut("Iterator !=", iter1 != iter2, false);

resultOut("Iterator ++ postfix", *(iter1++), 30.0);

resultOut("Iterator ++ prefix", *(++iter1), 5.0);

return 0;

}

template

void resultOut(const char* testName, T result, T expected) {

std::cout << (result == expected ? "Pass" : "Fail")

<< " : "

<< testName

<< std::endl;

}

-----------------------------------------------------------------------

#include "node1.h"

#include // Provides assert

#include // Provides NULL and size_t

using namespace std;

namespace bagiter

{

size_t list_length(const node* head_ptr)

// Library facilities used: cstdlib

{

const node *cursor;

size_t answer;

answer = 0;

for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( ))

++answer;

return answer;

}

void list_head_insert(node*& head_ptr, const node::value_type& entry)

{

head_ptr = new node(entry, head_ptr);

}

void list_insert(node* previous_ptr, const node::value_type& entry)

{

node *insert_ptr;

insert_ptr = new node(entry, previous_ptr->link( ));

previous_ptr->set_link(insert_ptr);

}

node* list_search(node* head_ptr, const node::value_type& target)

// Library facilities used: cstdlib

{

node *cursor;

for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( ))

if (target == cursor->data( ))

return cursor;

return NULL;

}

const node* list_search(const node* head_ptr, const node::value_type& target)

// Library facilities used: cstdlib

{

const node *cursor;

for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( ))

if (target == cursor->data( ))

return cursor;

return NULL;

}

node* list_locate(node* head_ptr, size_t position)

// Library facilities used: cassert, cstdlib

{

node *cursor;

size_t i;

assert (0 < position);

cursor = head_ptr;

for (i = 1; (i < position) && (cursor != NULL); i++)

cursor = cursor->link( );

return cursor;

}

const node* list_locate(const node* head_ptr, size_t position)

// Library facilities used: cassert, cstdlib

{

const node *cursor;

size_t i;

assert (0 < position);

cursor = head_ptr;

for (i = 1; (i < position) && (cursor != NULL); i++)

cursor = cursor->link( );

return cursor;

}

void list_head_remove(node*& head_ptr)

{

node *remove_ptr;

remove_ptr = head_ptr;

head_ptr = head_ptr->link( );

delete remove_ptr;

}

void list_remove(node* previous_ptr)

{

node *remove_ptr;

remove_ptr = previous_ptr->link( );

previous_ptr->set_link( remove_ptr->link( ) );

delete remove_ptr;

}

void list_clear(node*& head_ptr)

// Library facilities used: cstdlib

{

while (head_ptr != NULL)

list_head_remove(head_ptr);

}

void list_copy(const node* source_ptr, node*& head_ptr, node*& tail_ptr)

// Library facilities used: cstdlib

{

head_ptr = NULL;

tail_ptr = NULL;

// Handle the case of the empty list.

if (source_ptr == NULL)

return;

// Make the head node for the newly created list, and put data in it.

list_head_insert(head_ptr, source_ptr->data( ));

tail_ptr = head_ptr;

// Copy the rest of the nodes one at a time, adding at the tail of new list.

source_ptr = source_ptr->link( );

while (source_ptr != NULL)

{

list_insert(tail_ptr, source_ptr->data( ));

tail_ptr = tail_ptr->link( );

source_ptr = source_ptr->link( );

}

}

}

------------------------------------------------------------------------------

Example Output

30 15 5 45 30 15 5 Pass : Iterator * Pass : Iterator == Pass : Iterator != Pass : Iterator == Pass : Iterator != Pass : Iterator ++ postfix Pass : Iterator ++ prefix
/* NODE_ITERATOR_H_ */

--------------------------------------------------

This is my code:

#ifndef BAGI_H_

#define BAGI_H_

#include "node_iterator.h"

#include "bag3.h"

namespace bagiter

{

template

//Extend the bag class by adding an iterator

class bagi: public bag {

typedef node_iterator iterator;

public:

bagi();

~bagi();

iterator begin() //Will need to implement begin() and end() member functions here

{

return iterator(head_ptr);

}

iterator end () //Will need to implement begin() and end() member functions here

{

return iterator();

}

//Overrides if any required

//They will return an iterator, which is a new class (node_iterator)

//you need to create

//The member functions will return iterator(/*value in here*/)

};

}

#endif /* BAGI_H_ */

--------------------------------------------------

#ifndef NODE_ITERATOR_H_

#define NODE_ITERATOR_H_

#include // Provides iterator and forward_iterator_tag

#include "node1.h"

namespace bagiter

{

class node_iterator : public std::iterator

{

public:

node_iterator(node * initial = nullptr)

{

current = initial; //Constructor

}

node::value_type& operator *( ) const

{

return current->data();//should give the the value the iterator points to

}

node_iterator& operator ++( ) // Prefix ++

{

current = current->link();

return *this; //Move to the next node

}

node_iterator operator ++(int) // Postfix ++

{

node_iterator original (current);

current = current->link( );

return original;

//Move to the next node, however, return a copy of what the old node

}

bool operator ==(const node_iterator other) const

{

return current == other.current; //Pointing at SAME NODE?

}

bool operator !=(const node_iterator other) const

{

return current != current;//Not pointing at SAME NODE?

}

private:

node * current;

};

}

#endif /* NODE_ITERATOR_H_ */

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!