请大家帮忙结局一个C++链表的有关问题,在编译时会出错

请大家帮忙结局一个C++链表的问题,在编译时会出错
。h
#ifndef LIST_H
#define LIST_H

#include"ListNode.h"

template< typename NODETYPE >
class List
{
public:
List(); 
~List();
void insertAtFirst( const NODETYPE & );
void insertAtLast( const NODETYPE & );
bool removeFromFront( NODETYPE & );
bool removeFromBack( NODETYPE & );
bool isEmpty() const;
void print() const;
private:
ListNode< NODETYPE > *firstPtr;
ListNode< NODETYPE > *lastPtr;
ListNode< NODETYPE > *getNewNode( const NODETYPE & ); 
};

#endif

.h
#ifndef LISTNODE_H
#define LISTNODE_H

template< typename NODETYPE > class List;

template< typename NODETYPE > 
class ListNode
{
friend class List< NODETYPE >;

public:
ListNode( const NODETYPE & ) ;
NODETYPE getData( ) const ;
private:
NODETYPE data;
ListNode< NODETYPE > *nextPtr;
};

#endif


.cpp
#include"List.h"
#include<iostream>
using namespace std;

template< typename NODETYPE >
List< NODETYPE >::List():firstPtr( NULL ),lastPtr( NULL )
{

}

template< typename NODETYPE >
List< NODETYPE >::~List()
{
if( !isEmpty() )
{
ListNode< NODETYPE > *currentPtr=firstPtr;
ListNode< NODETYPE > *tempPtr=NULL;

while( currentPtr!=NULL )
{
tempPtr=currentPtr;
cout<<tempPtr->data<<"\t";
currentPtr=currentPtr->nextPtr;
delete tempPtr;
}
}
}

template< typename NODETYPE >
void List< NODETYPE >::insertAtFirst( const NODETYPE &value)
{
ListNode< NODETYPE > *newPtr=getNewNode( value )

if( isEmpty() )
{
firstPtr=lastPtr=newPtr;
}
else
{
newPtr->nextPtr=firstPtr;
firstPtr=newPtr;
}
}

template< typename NODETYPE >
void List< NODETYPE >::insertAtLast( const NODETYPE &value )
{
ListNode< NODETYPE > *newPtr=getNewNode( value );

if( isEmpyt() )
{
firstPtr=lastPtr=newPtr
}
else
{
newPtr->nextPtr=firstPtr;
firstPtr=newPtr;
}
}

template< typename NODETYPE > 
bool List< NODETYPE >::removeFromFront( NODETYPE &value )
{
if( isEmpty() )
{
return false;
}
else
{
ListNode< NODETYPE > *tempPtr=firstPtr;

if( firstPtr==lastPtr )
{
firstPtr=lastPtr=NULL;
delete tempPtr;
return true;
}
else 
{
firstPtr=firstPtr->nextPtr;
value=tempPtr->data;
delete tempPtr;
return true;
}
}
}

template< typename NODETYPE >
bool List< NODETYPE >::removeFromBack( NODETYPE &value )
{
if( isEmpty() )
{
return false;
}
else
{
ListNode< NODETYPE > *tempPtr=lastPtr;

if( firstPtr==lastPtr )
{
firstPtr=lastPtr=NULL;
delete tempPtr;
return true;
}
else
{
ListNode< NODETYPE > *currentPtr=firstPtr;

while( cuurentPtr!=lastPtr )
{
currentPtr=currentPtr->nextPtr;
}
lastPtr=currentPtr;
currentPtr->nextPtr=NULL;
value=tempPtr->data;
delete tempPtr;
return true;
}
}
}

template< typename NODETYPE >
bool List< NODETYPE >::isEmpty() const
{
return ( firstPtr==NULL );
}

template< typename NODETYPE > 
ListNode< NODETYPE > *List< NODETYPE >::getNewNode( const NODETYPE &value )
{
return ( new ListNode< NODETYPE >( value ) );
}

template< typename NODETYPE >
void List< NODETYPE >::print() const
{
if( isEmpty() )
{
cout<<"The list is empty"<<endl;
return;
}

ListNode<NODETYPE> *currentPtr=firstPtr;

cout<<"The list is:"<<endl;

while( currentPtr!=NULL )
{
cout<<currentPtr->data;
currentPtr=currentPtr->nextPtr;
}

cout<<"\n\n";

}




.cpp
#include"ListNode.h"

template< typename NODETYPE > 
ListNode < NODETYPE > ::ListNode(const NODETYPE& info ):data( info ), nextPtr( NULL )