Reputation: 7879
Trying to learn C++. I'm getting an error in my code, in the line:
class LinkedList : public LinkedList<T> {
The error says:
invalid use of incomplete type 'class LinkedList, std::allocator > >' declaration of 'class LinkedList, std::allocator > >'
Can anyone point out what I'm doing wrong? Here is the entire code.
#ifndef LINKEDLIST_HPP
#define LINKEDLIST_HPP
#include <iostream>
using namespace std;
template <class T>
class LinkedList : public LinkedList<T> {
private:
// a ListNode consists of the item and a pointer to the next ListNode
struct ListNode {
T data;
ListNode *next;
};
int size; //Size of the list
ListNode *head; //the beginning of the list
public:
LinkedList(); // default oonstructor
~LinkedList(); // destructor
virtual bool isEmpty ();
virtual int getLength ();
virtual void insert (int pos, T item);
virtual T remove (int pos);
virtual T retrieve (int pos);
//helper methods
LinkedList(LinkedList ©List); //copy constructor
ListNode *find (int pos) const; // internal find function
};
//default constructor
template <class T>
LinkedList<T>::LinkedList() {
size = 0;
head = NULL;
}
//destructor
template <class T>
LinkedList<T>::~LinkedList() {
//loop through each node, and delete it
ListNode* current = head;
while (current != NULL) {
ListNode* next = current->next;
delete current;
current = next;
}
head = NULL; // set head node to back to null
}
//copy constructor
template <class T>
LinkedList<T>::LinkedList(LinkedList& copyList) {
size = copyList.size;
// if copyList is empty
if (copyList.head == NULL)
head = NULL;
else {
//create a new head
head = new ListNode;
head->data = copyList.head->data;
//create a new list
ListNode *newPtr = head; // start at the head
// iterate through rest of list to be copied
for (ListNode *copyPtr = copyList.head->next; copyPtr != NULL; copyPtr = copyPtr->next) {
newPtr->next = new ListNode;
newPtr->data = copyPtr->data;
}
//make last ListNode's next point to NULL
newPtr->next = NULL;
}
}
template <class T>
bool LinkedList<T>::isEmpty() {
if (size == 0)
return true;
return false;
}
template <class T>
int LinkedList<T>::getLength() {
return size;
}
// used in other methods to find a given index
template <class T>
LinkedList<T>::ListNode LinkedList<T>::find(int pos) const {
// check that pos is in bound of LinkedList
if ((pos < 1) || pos > getLength()) {
cout << "Find position of out bounds" << endl;
return NULL;
} else { //search through ListNodes
ListNode *temp = head; // start at the head
for (int i = 1; i < pos; ++i)
temp = temp->next;
return temp;
}
}
template <class T>
T LinkedList<T>::retrieve(int pos) {
T tempData; // to hold retrieved data
try {
if ((pos < 1) || (pos > getLength())) {
cout << "Retrieve request outside LinkedList's bounds" << endl;
return NULL;
}
else { //traverse list
ListNode *temp = find(pos);
tempData = temp->data;
return tempData;
}
} catch (int e) {
cout << "Could not retrieve position " << pos << endl;
}
}
template <class T>
void LinkedList<T>::insert(int pos, T item) {
//check bounds
if ((pos < 1) || (pos > getLength() +1))
cout << "Must insert at a position between 1 and getLength() + 1" << endl;
else {
try {
//create new ListNode
ListNode *temp = new ListNode;
temp->data = item;
//if the new item is at the first position
if (pos == 1) {
temp->next = head;
head = temp;
}
else {
ListNode *prev = find(pos - 1);
temp->next = prev->next;
prev->next = temp;
}
//increment size
++size;
} catch (int e) {
cout << "Error inserting " << item << " at position " << pos << endl;
}
}
}
template <class T>
T LinkedList<T>::remove(int pos) {
//check bounds
if ((pos < 1) || (pos > getLength()))
cout << "Must remove a position between 1 and getLength()" << endl;
else {
try {
ListNode *temp; //to hold shifted node
//if node to be deleted is first node
if (pos == 1) {
temp = head;
head = head->next;
}
//for anything but the head
//write over the node before the pos'th index
else {
ListNode *prev = find(pos - 1);
temp = prev->next;
prev->next = temp->next;
}
//destroy temp, to free up memory
temp->next = NULL;
delete temp;
//decrement size
--size;
} catch (int e) {
cout << "Error removing item from position " << pos << endl;
}
}
}
#endif /* LINKEDLIST_HPP */
Upvotes: 0
Views: 982
Reputation: 9721
Nawaz gave the right answer.
Just to give a few off-topic informations :
make your destructor virtual (even if inheriting from a templated container is not something very c++-ish).
Use const where it belongs :
LinkedList(const LinkedList ©List); //copy constructor
virtual bool isEmpty () const;
// etc.
Obviously, in real life you would use an stl container like std::list ;)
Upvotes: 1
Reputation: 361812
template <class T>
class LinkedList : public LinkedList<T> {
This doesn't make sense. It is like this:
class A : public A
Does this make sense to you? How exactly?
The class you're deriving from doesn't exist, rather it is being defined while you're deriving from it, so the compiler doesn't know what the base supposed to be. The compiler need to know the full definition of the base class before you derive from it.
Upvotes: 5