The Code

List.h
#pragma once template<typename T> class List { public: List(); ~List(); bool push_back(T*); void clear(); bool empty(); T* front(); T* back(); void pop_front(); size_t size(); private: size_t tSize, nSize, lSize; struct lNode { lNode* next; T* data; }; struct { lNode *lStart = NULL; lNode *lEnd = NULL; }lList; lNode* createNode(const T*); void deleteList(); }; // constructor and destructor template<typename T> List<T>::List() { tSize = sizeof(T); nSize = sizeof(lNode); lSize = 0; } template<typename T> List<T>::~List() { deleteList(); } //public methods template<typename T> bool List<T>::push_back(T* data) { lNode* nNode = createNode(data); if (nNode == NULL) { return false; } if (lList.lStart == NULL) { lList.lStart = lList.lEnd = nNode; } else { lList.lEnd = lList.lEnd->next = nNode; } lSize++; return true; } template<typename T> void List<T>::clear() { deleteList(); } template<typename T> bool List<T>::empty() { return (lList.lStart = NULL); } template<typename T> size_t List<T>::size() { return lSize; } template<typename T> T* List<T>::front() { if (lList.lStart) { return lList.lStart->data; } return NULL; } template<typename T> T* List<T>::back() { if (lList.lEnd) { return lList.lEnd->data; } return NULL; } template<typename T> void List<T>::pop_front() { if (lList.lStart) { lNode* d = lList.lStart; lList.lStart = d->next; free(d->data); free(d); lSize--; } } // private methods template<typename T> typename List<T>::lNode* List<T>::createNode(const T* t) { lNode* nNode = (lNode*)malloc(nSize); if (nNode != NULL) { nNode->data = (T*)malloc(tSize); if (nNode->data == NULL) { return NULL; } memcpy(nNode->data, t, tSize); nNode->next = NULL; } return nNode; } template<typename T> void List<T>::deleteList() { lNode* dNode = lList.lStart; while (dNode != NULL) { lList.lStart = dNode->next; free(dNode->data); free(dNode); dNode = lList.lStart; lSize = 0; } lList.lEnd = lList.lStart = NULL; }


Queue.h
#pragma once #include "List.h" template<typename T> class Queue : public List<T> { public: bool push(T*); void pop(); T deQueue(); T front2(); }; template<typename T> bool Queue<T>::push(T* t) { return (this->push_back(t)); } template<typename T> void Queue<T>::pop() { this->pop_front(); } template<typename T> T Queue<T>::deQueue() { T* t = this->front(); T tt = *t; this->pop_front(); return tt; } template<typename T> T Queue<T>::front2() { T* t = this->front(); return *t; }


Queue.cpp
#include "stdafx.h" #include <stdint.h> #include <stdlib.h> #include <iostream> #include "Queue.h" using namespace std; int main() { Queue<int> queue; for (int i = 0; i < 10; i++) { int l = rand() % 23; queue.push(&l); } cout << "Front: " << queue.front2() << " Back: " << *queue.back() << '\n'; queue.pop(); cout << "After pop Front: " << *queue.front() << " Back: " << *queue.back() << " Size: " << queue.size() << '\n'; cout << "Testing deQueue: " << queue.deQueue() << '\n'; cin.get(); return 0; }


Queue.ino
#include "Queue.h" template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; } void setup() { Serial.begin(115200); Queue<int> queue; for (int i = 0; i < 10; i++) {     int l = rand() % 23;     queue.push(&l); } Serial << "Loaded\n"; Serial << "Front: " << *queue.front() << " Back: " << *queue.back() << '\n'; queue.pop(); Serial << "After pop Front: " << *queue.front() << " Back: " << *queue.back() << " Size: " << queue.size() << '\n'; }


Read the chapter in my book C++ Data Structures with immediate download from Amazon