The queue class needs to inherit protectedly from the list class

My code won't compile because of this line towards the bottom
listPtr = &myqueue;
if i comment out this line, it compiles and runs, but without this line i can't do what i want. I need this line to work in order to continue working on this project.

what i need to be able to do is assign a pointer of type list<T>, to an address of type queue<T> (T is "datatype" in this code.)

the first section is the driver class for my list and queue classes. It basically tests the functions out. it creates a list(a doubly linked circular list) of type char and manipulates it. Then a queue is created and manipulated.

the second section is the function definitions. They should be in a file called listAndQueue.h.

any help you guys could give would be very apreciated.

Let me know what questions you have.

#include <iostream>
#include <cstdlib>
#include "listAndQueue.h"
using namespace std;
using namespace BS_ADT;
//--------------------------------------------------------------------
// simple driver to test list
//--------------------------------------------------------------------
int main(void)
{
	try
	{
		using BS_ADT::list; // not the same as std::list<class T>
		list<char> * listPtr;
		list<char> mylist(1,'X');
		listPtr = &mylist;

		listPtr->push_front('1');
		listPtr->push_front('2');
		listPtr->push_front('Y');
		list<char> mylist2 = mylist;
		cout << "mylist: " << mylist << "mylist2: "<< mylist2 << endl;
		mylist2.release();
		listPtr->push_front('p');
		listPtr->push_front('Z');
		cout << listPtr->pop_front() << endl;
		mylist2 = mylist; // a copy
		cout << "mylist: " << mylist << "mylist2: "<< mylist2 << endl;

		listPtr->push_back('A');
		listPtr->push_back('A');
		listPtr->push_back('A');
		listPtr->push_back('B');
		cout << "mylist: " << mylist << "mylist2: "<< mylist2 << endl;
		cout << listPtr->pop_back() << endl;
		mylist2 = mylist; // a copy
		cout << "mylist: " << mylist << "mylist2: "<< mylist2 << endl;

		// create a new iterator pointing to the beginning of mylist
		list<char>::iterator listit(mylist.begin());
		cout << listit++->data << " ";
		cout << listit->data << endl;
		cout << listit--->data << " ";
		cout << listit->data << endl;
		mylist.release();	
		list<char> mylist3(mylist2.begin(), mylist2.end());
		cout << "mylist" << mylist << endl << "mylist2" << mylist2 << endl << "mylist3" << mylist3 << endl;
	
		cout << "NOW IT'S TIME TO TEST QUEUES" << endl;

		queue<char> myqueue(1,'h');
		queue<char> myqueue2(4,'2');
		char j = 'i';
		myqueue.push(j);
		j = 'j';
		myqueue.push(j);
		j = 'k';
		myqueue.push(j);

		myqueue2 = myqueue;
		listPtr = &myqueue;
		//above line doesn't work.
	
		cin.get(); // keep window open
		cout << myqueue;
	
		j = 'l';

		cout << "pop from the queue: " << myqueue.pop() << endl;
		cout << "pop from the queue: " << myqueue.pop() << endl;
		cout << myqueue;
		cout << "pop from the queue: " << myqueue.pop() << endl;
		cout << "pop from the queue: " << myqueue.pop() << endl;
		cout << "pop from the empty queue: " << myqueue.pop() << endl;

		cin.get();
		return EXIT_SUCCESS;
	}
	catch(exception e)
	{

	}
}
#include <iostream>
using namespace std;
// namespace std has its own list -- we won't use it here
namespace BS_ADT
{
	template<class datatype>
	class list
	{
	public:
	  struct listelem; // forward declarations
	  class iterator;
	  friend class iterator;
	  // constructors
	  list() : head(NULL), tail(NULL), m_size(0) {}
	  list(size_t n_elements, datatype c); 
	  list(const list& x);
	  list(iterator b, iterator e);

	  ~list() { release(); } // destructor
	  virtual unsigned getSize()const {return m_size;} // accessor
	  virtual iterator begin()const { return head; }
	  virtual iterator end()const {return tail;}
	  void push_front(datatype datum);
	  datatype pop_front(); 
	  void push_back(datatype datum);
	  datatype pop_back(); 
	  datatype& front(){return head->data;}
	  datatype& back() {return tail->data;}
	  virtual bool empty()const{ return m_size <= 0;}
	  virtual void release();
	  virtual list operator=(const list & rlist);
	private:
		listelem *head;
		listelem *tail;
		unsigned m_size;
	public:
	//--------------------------------------------------------------------
	// scoped within class list !
	//--------------------------------------------------------------------
	  struct listelem // list cell
	  {
		 datatype data;
		 listelem *next; 
		 listelem *prev; 
		 listelem(datatype c, listelem* p, listelem* n)
			 :data(c), prev(p), next(n){} // struct constructor
	  };

	//--------------------------------------------------------------------
	// scoped within class list !
	//--------------------------------------------------------------------
	  class iterator
	  {
	  public:
		iterator(listelem* p = NULL) :ptr(p){}
		iterator operator++(); 
		iterator operator--();
		iterator operator++(int);
		iterator operator--(int);
		listelem* operator->() {return ptr;};
		datatype& operator*() {return ptr -> data;}
		operator listelem*() {return ptr;}
	  private:
		listelem* ptr; 
	  }; 
	}; 

	template<class datatype>
	ostream& operator<<(ostream& out, const list<datatype>& x);

	//--------------------------------------------------------------------
	// constructor
	//--------------------------------------------------------------------
	template<class datatype>
	list<datatype>::list(size_t n_elements, datatype c)
		:m_size(0), head(NULL), tail(NULL)
	{
		if(n_elements <= 0)
			throw new exception("0 or less elements");
		for(size_t i = 0; i < n_elements; ++i)
			push_front(c);
	}
	
	//--------------------------------------------------------------------
	// copy constructor
	//--------------------------------------------------------------------
	template<class datatype>
	list<datatype>::list(const list& x)
		:m_size(0), head(NULL), tail(NULL)
	{
		list::iterator r = x.begin();
		int size = x.getSize();
		while ((size--) > 0)
			push_back(*r++);
	}
	
	//--------------------------------------------------------------------
	// another constructor
	//--------------------------------------------------------------------
	template<class datatype>
	list<datatype>::list(iterator b, iterator e)	
		:m_size(0), head(NULL), tail(NULL)
	{
		list::iterator it = b;
		do 
			push_back(*it++);
		while (it != e->next);
	}

	//--------------------------------------------------------------------
	// empties the list
	//--------------------------------------------------------------------
	template<class datatype>
	void list<datatype>::release() 
	{
		while (head != NULL)
			pop_front();
	}
	
	//--------------------------------------------------------------------
	// operator<< for the list
	//--------------------------------------------------------------------
	template<class datatype>
	ostream& operator<<(ostream& out, const list<datatype>& x)
	{
		list<datatype>::iterator p = x.begin();
		out << "list = (";
		int size = x.getSize();
		while ((size--) > 0)
		{
			out << *p;
			if(p != x.end())
				out << ","; 
			++p;	//advances iterator using next
		}
		cout << ")\n";
		return out;
	}
	
	//--------------------------------------------------------------------
	// adds c to the front of the list
	//--------------------------------------------------------------------
	template<class datatype>
	void list<datatype>::push_front(datatype datum)
	{
		listelem* temp = new listelem(datum, NULL, head);
		
		if (!empty())	//was a nonempty list
		{
			head->prev = temp;
			temp->next = head;
			temp->prev = tail;
			tail->next = temp;
			head = temp;
		}
		else			//was an empty list
		{
			head = tail = temp;
			head->prev = temp;
			head->next = temp;
			tail->next = temp;
			tail->prev = temp;
		}
		m_size++;
	} 

	//--------------------------------------------------------------------
	// adds c to the back of the list
	//--------------------------------------------------------------------
	template<class datatype>
	void list<datatype>::push_back(datatype datum)
	{
		listelem* temp = new listelem(datum, tail, NULL);
		
		if (!empty())	//was a nonempty list
		{ 	
			head->prev = temp;
			temp->next = head;
			temp->prev = tail;
			tail->next = temp;
			tail = temp;
		}
		else			//was an empty list
		{
			head = tail = temp;
			head->prev = temp;
			head->next = temp;
			tail->next = temp;
			tail->prev = temp;
		}
		m_size++;
	} 

	//--------------------------------------------------------------------
	// overloaded =
	//--------------------------------------------------------------------
	template<class datatype>
	list<datatype> list<datatype>::operator=(const list<datatype> & rlist)
	{
		if(&rlist != this)
		{
			list<datatype>::iterator r_it = rlist.begin();
			release();
			int size = rlist.getSize();
			while ((size--) > 0)
				push_back(*r_it++);
		}
		return *this;
	}

	//--------------------------------------------------------------------
	// pre-increment for the iterator
	//--------------------------------------------------------------------
	template<class datatype>
	typename list<datatype>::iterator list<datatype>::iterator::operator++()
	{
		if(ptr == NULL)
			throw exception("NULL pointer");
		ptr = ptr->next;
		return *this;
	} 
	
	//--------------------------------------------------------------------
	// post-decrement for the iterator
	//--------------------------------------------------------------------
	template<class datatype>
	typename list<datatype>::iterator list<datatype>::iterator::operator--(int)
	{
		if(ptr == NULL)
			throw exception("NULL pointer");
		iterator temp = *this;
		ptr = ptr->prev;
		return temp;
	} 
	
	//--------------------------------------------------------------------
	// pre-decrement for the iterator
	//--------------------------------------------------------------------
	template<class datatype>
	typename list<datatype>::iterator list<datatype>::iterator::operator--()
	{
		if(ptr == NULL)
			throw exception("NULL pointer");
		ptr = ptr->prev;
		return *this;
	} 
	
	//--------------------------------------------------------------------
	// post-increment for the iterator
	//--------------------------------------------------------------------
	template<class datatype>
	typename list<datatype>::iterator list<datatype>::iterator::operator++(int)
	{
		if(ptr == NULL)
			throw exception("NULL pointer");
		iterator temp = *this;
		ptr = ptr->next;
		return temp;
	} 
	
	//--------------------------------------------------------------------
	// removes and returns first element
	//--------------------------------------------------------------------
	template<class datatype>
	datatype list<datatype>::pop_front()
	{
		if(!empty())
		{
			m_size--;
			datatype data = head->data;
			iterator temp = begin();
			temp++;
			delete head;
			head = temp;
			if(!empty())
			{
				head->prev = tail;
				tail->next = head;
			}
			else
			{
				tail = NULL;
				head = NULL;
			}
			return data;
		}
		else return static_cast<datatype>(NULL);
	}
	
	//--------------------------------------------------------------------
	// removes and returns last element
	//--------------------------------------------------------------------
	template<class datatype>
	datatype list<datatype>::pop_back(void)
	{
		if(!empty())
		{
			m_size--;
			datatype data = tail->data;
			iterator temp = end();
			temp--;
			delete tail;
			head->prev = temp;
			tail = temp;
			if(tail != NULL)
			{
				tail->next = head;
			}
			else
			{
				head = NULL;
				tail = NULL;
			}
			return data;
		}
		else return static_cast<datatype>(NULL);
	}

	template<class datatype>
	class queue : protected list<datatype>
	{
	public:
		queue() : list() {}
		queue(size_t n_elements, datatype c) : list(n_elements, c) {} 
		queue(const queue& x) : list(dynamic_cast<const list &>(x)) {}
		queue(const list& x) : list(dynamic_cast<const list &>(x)) {}
		queue(iterator b, iterator e) : list(dynamic_cast<const iterator &>(b),
			dynamic_cast<const iterator &>(e)){}
		virtual unsigned getSize() const {return list::getSize();} // accessor
		virtual iterator begin()const {return list::begin(); }
		virtual iterator end()const {return list::end();}
		void push(datatype& element) {list::push_back(element);}
		datatype pop() {return list::pop_front();}

		queue operator=(const queue<datatype> & rlist)
		{
			if(&rlist != this)
			{
				queue<datatype>::iterator r_it = rlist.begin();
				release();
				int size = rlist.getSize();
				while ((size--) > 0)
					push_back(*r_it++);
			}
			return *this;
		}
	};
	

	//template<class datatype>
	//ostream& operator<<(ostream& out, const queue<datatype>& x);

	template<class datatype>
	ostream& operator<<(ostream& out, const queue<datatype>& x)
	{
		list<datatype>::iterator p = x.begin();
		out << "queue = (";
		int size = x.getSize();
		while ((size--) > 0)
		{
			out << *p;
			if(p != x.end())
				out << ","; 
			++p;	//advances iterator using next
		}
		cout << ")\n";
		return out;
	}
} // end namespace BS_ADT

Recommended Answers

All 2 Replies

I do not think you can do that. A pointer of list pointing to a queue. That should not be compatible. Btw, what is the compilation error message that you get?

It is perfectly feasible to have a base class pointer point to a derived class. That is the primary technique for doing object oriented programming (in a language with pointers). However it is usually done with classes that inherit public, not protected. Agree with chiwawa10: Precisely what is the compiler telling you? Which compiler?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.