Subj : Simple template linking problem To : borland.public.cpp.borlandcpp From : Colin Date : Wed Sep 10 2003 05:46 pm I am trying to create and use a simple double-linked list template class in BC++ 4.5 which compiles fine, but the linker cannot resolve 4 of the 9 public methods, but is happy with the other 5. Why? This is the template declaration: //--------------------------------------------------------------------------- template class TListObj { friend TList; private: TListObj *prior; TListObj *next; protected: T *Object; public: TListObj(void); // Default Constructor TListObj(T *ptr); // Constructor with a pointer to object virtual ~TListObj(); // Destructor }; //--------------------------------------------------------------------------- template class TList { private: TListObj *first; TListObj *last; int count; public: TList(void); // Default constructor virtual ~TList(); int Add(T *ptr); bool Delete(int index); T *Last() {if (last) return last->Object; else return NULL;}; T *First() {if (first) return first->Object; else return NULL;}; T *Get(int index); int Count() {return count;}; void Clear(void); }; //--------------------------------------------------------------------------- and this the implementation: //--------------------------------------------------------------------------- TListObj::TListObj(void) { Object = NULL; prior = NULL; next = NULL; }; //--------------------------------------------------------------------------- TListObj::TListObj(T *ptr) { Object = ptr; prior = NULL; next = NULL; }; //--------------------------------------------------------------------------- TListObj::~TListObj() { delete Object; }; //--------------------------------------------------------------------------- // TList Class - Maintains a doubly linked list of pointers to objects //--------------------------------------------------------------------------- TList::TList(void) { first = NULL; last = NULL; count = 0; }; //--------------------------------------------------------------------------- TList::~TList() { Clear(); }; //--------------------------------------------------------------------------- int TList::Add(T *ptr) { TListObj *obj = new TListObj(ptr); if (last) // is there a last object in the list { last->next = obj; // previous end points to this object obj->prior = last; // this object's prior is the old last obj->next = NULL; // set the next pointer to NULL (this is the last object) last = obj; // last is now this object } else // no, then this must be the start of the list { obj->prior = NULL; obj->next = NULL; first = obj; last = obj; } return ++count; }; //--------------------------------------------------------------------------- bool TList::Delete(int index) { TListObj *Obj = first; if (!Obj) // if there is no first, return return false; while(index-- > 0 && Obj) // iterate through index number of objects Obj = Obj->next; if (Obj && index==-1) // make sure we have an object and we are at the right one! { if (Obj->prior) // does this object have a prior one (Obj->prior)->next = Obj->next; else // no, it is the first in the list first = Obj->next; // so the next object becomes the first if (Obj->next) // does this object have a next one (Obj->next)->prior = Obj->prior; else // no, it is the last one in the lst last = Obj->prior; // so the prior object becomes the last delete Obj; --count; return true; } return false; }; //--------------------------------------------------------------------------- // Clear the whole list void TList::Clear(void) { TListObj *Obj = first; if (!Obj) // if there is no first, return return; while(Obj) { Obj = first->next; delete first; first = Obj; --count; } first = NULL; last = NULL; }; //--------------------------------------------------------------------------- T* TList::Get(int index) { if (!first) // if there is no first, return NULL return NULL; TListObj *Obj = first; // point to the first for(int i=0; inext; // point to the next object if (!Obj) // if we got to the end return NULL; // return NULL } return Obj->Object; // return the object found }; //--------------------------------------------------------------------------- Now the test program to use this lot.... int main() { int count = 0; int i; TList *L = new TList(); // make a list for TCommBuffer objects // populate the list with some TCommBuffers for(i=0; i<10; i++) { TCommBuffer *Buff = new TCommBuffer(); count = L->Add(Buff); printf("%d\n", count); } // delete the 5th object L->Delete(5); // delete the 5th object printf("Count = %d\n", L->Count()); // and the 0th (first) object L->Delete(0); // delete the first object printf("Count = %d\n", L->Count()); // delete the rest of the objects now, but not the last one TCommBuffer *Last = L->Last(); do { TCommBuffer *First = L->First(); if (First && Last && First == Last) { printf("Only one object left in List\n"); break; } L->Delete(0); printf("Count = %d\n", L->Count()); }while(1); // clean up - deletes any remaining objects delete L; return 0; }; TCommBuffer class declaration: // Communications Buffer Class - Provides a buffer for incomming messages with status class TCommBuffer { private: int Size; char Protocol; int Port; short Length; bool IsRx; dword ErrorStatus; TTime TimeStamp; byte* Buffer; // Placeholder for the message received public: TCommBuffer(void); // DEFAULT CONSTRUCTOR TCommBuffer(TComms *C, bool Rx); // COMMS CONSTRUCTOR TCommBuffer(const TCommBuffer *C); // COPY CONSTRUCTOR virtual ~TCommBuffer(); // DESTRUCTOR TCommBuffer& operator = (const TCommBuffer& C); // ASSIGNMENT OPERATOR }; Finally (!) this all compiles okay, (and I have a project that includes all the relevant sources), but the linker cannot resolve: Linker Error: Undefined symbol TList::Delete(int) in module listtest.cpp Linker Error: Undefined symbol TList::Add(TCommBuffer far*) in module listtest.cpp Linker Error: Undefined symbol TList::TList() in module listtest.cpp Linker Error: Undefined symbol TList::~TList() in module listtest.cpp and yet the test app uses First, Last and Count ? What's going on??? TIA (oh, and sorry about the verbosity, but I thought you'd like to see the whole code!!!!) .