was bored at work so i decided to implement a linked list. tell me what u think....all criticism is welcomed. i'm here to learn it does not have every single method. (wasn't that bored). oh and i want to know if there's a way u can avoid writing *template<class T>* before every method besides using *define*. below is just the class.

Code:

template <class T>
class LinkedList
{
private:
struct node {
T data;
struct node * next,
* prev;
};
T getDataAtNode(int index);
struct node * head,
* end;
public:
LinkedList();
LinkedList(T data);
void push(T data);
T pop();
T operator[](int index);
bool isEmpty();
void clear();
int length();
};
template <class T>
T LinkedList<T>::getDataAtNode(int index)
{
int c = 0; struct node * iter = head;
while(iter)
{
if (c++ == index)
return iter->data;
iter = iter->next;
}
return NULL;
}
template <class T>
LinkedList<T>::LinkedList()
{
head = new node();
head->data = NULL;
head->next = NULL;
head->prev = NULL;
end = head;
}
template <class T>
LinkedList<T>::LinkedList(T data)
{
if (head != end)
{
head = new node();
end = head;
}
head->data = data;
head->next = NULL;
head->prev = NULL;
}
template <class T>
T LinkedList<T>::operator[](int index)
{
return (getDataAtNode(index));
}
template <class T>
void LinkedList<T>::push(T data)
{
if(head->data == NULL)
{
head->data = data;
}
else {
struct node * new_node = new node();
new_node->data = data;
new_node->next = NULL;
new_node->prev = end;
end->next = new_node;
end = new_node;
}
}
template <class T>
T LinkedList<T>::pop()
{
T data = end->data;
if(end->prev)
{
end = end->prev;
}
else
{
end = head;
head->data = NULL;
}
end->next = NULL;
return data;
}
template <class T>
bool LinkedList<T>::isEmpty()
{
return (head->data == NULL && head == end ? true : false);
}
template <class T>
void LinkedList<T>::clear()
{
end = head;
head->data = NULL;
head->next = NULL;
}
template <class T>
int LinkedList<T>::length()
{
int c = 0; struct node * iter = head;
while(iter)
{
c++;
iter = iter->next;
}
return c;
}