I'm getting the following errors when I try to build my c++ program in Xcode:
Undefined symbols for architecture x86_64:
"DoublyLinkedList::insertFront(int*)", referenced from: _main in main.o "DoublyLinkedList::print()", referenced from: _main in main.o "DoublyLinkedList::DoublyLinkedList()", referenced from: _main in main.o "DoublyLinkedList::~DoublyLinkedList()", referenced from: _main in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
My code works when I change the '#include "DoublyLinkedList.hpp"' to '#include "DoublyLinkedList.cpp"' in my 'main.cpp' file, but I'm just confused why my header file won't link. I've also used a make file and try to compile that way but get the same error. Code below.
DoublyLinkedList.hpp
#ifndef DoublyLinkedList_hpp
#define DoublyLinkedList_hpp
#include <stdio.h>
#include <iostream>
template <class T>
class DoublyLinkedList;
// LinkNode helper class for DoublyLinkedList
template <class T>
class LinkNode{
friend class DoublyLinkedList<T>;
public:
LinkNode(){next=NULL;prev=NULL;data=0;}
~LinkNode(){if (data){delete data;data=0;}
}
private:
T *data;
LinkNode *next;
LinkNode *prev;
};
//Doubly Linked List class with Templates
//insertFront - pointer to T - inserts at front
//insertRear - pointer to T - inserts at rear
template <class T>
class DoublyLinkedList{
public:
DoublyLinkedList();
~DoublyLinkedList();
T *getFirst();
T *getLast();
int getListSize();
void insertFront(T *);
void insertRear(T *);
T *removeFront();
T *removeRear();
void print();
private:
LinkNode<T> *first;
LinkNode<T> *last;
int listSize;
};
#endif //DoublyLinkedList_hpp
DoublyLinkedList.cpp
#include "DoublyLinkedList.hpp"
template <class T>
DoublyLinkedList<T>::DoublyLinkedList(){
first = last = NULL;
listSize=0;
}
//Deconstructor for DoublyLinkedList
template <class T>
DoublyLinkedList<T>::~DoublyLinkedList<T>(){
LinkNode<T> *link = first;
while (first){
link = first;
first = first-> next;
if (link->data){
delete link->data;
link->data=0;
}
delete link;
}
}
//Getters
template <class T>
T* DoublyLinkedList<T>::getFirst() {
return this->first;
}
template <class T>
T* DoublyLinkedList<T>::getLast() {
return this->last;
}
template <class T>
int DoublyLinkedList<T>::getListSize() {
return this->listSize;
}
//Insert node at the front of the list
template <class T>
void DoublyLinkedList<T>::insertFront(T *d){
LinkNode<T> *link = new LinkNode<T>();
T *nd = new T();
*nd = *d; //default memberwise copy
link->data = nd; //attach data
listSize++;
//link->prev stays at 0 (no change)
if (first == NULL){//if empty list
first = last = link;
return;
}
link->next = first;//first link becomes the second
link->prev = link;//previous is itself
first = link;//new node becomes first
}
//Insert node at the end of the list
template <class T>
void DoublyLinkedList<T>::insertRear(T *d){
LinkNode<T> *link = new LinkNode<T>();
T *nd = new T();
*nd = *d; // default memberwise copy
link->data = nd; // attach data
// link->prev stays at 0 no change
listSize++;
if(first == NULL){
first = last = link;
return;
}
last->next = link;
link->prev = last;
last = link;
}
//Removes first node and returns it
template <class T>
T *DoublyLinkedList<T>::removeFront(){
T *temp=0;
if (first == NULL) return NULL;//if empty list
// splice out data node
temp = first->data;
first->data = NULL;
listSize--;
if (first == last){
delete first;
first = last = NULL;
return temp;
}
LinkNode<T> *link = first;
first->next->prev = NULL;
first=first->next;
delete link;
return temp;
}
template <class T>
T *DoublyLinkedList<T>::removeRear(){
T *temp=NULL;
if (last == NULL) return NULL;//if empty list
// splice out data node
temp = last->data;
last->data = NULL;
listSize--;
if (first == last){
delete last;
first = last = NULL;
return temp;
}
LinkNode<T> *todel = last;
last->prev->next = NULL;
last = last->prev;
delete todel; // delete node that was formerly last
return temp;
}
template <class T>
void DoublyLinkedList<T>::print(){
LinkNode<T> *link = first;
while(link){
std::cout << *(link->data) << " ";
link = link->next;
}
std::cout << std::endl;
}
main.cpp
#include <iostream>
#include "DoublyLinkedList.hpp"
int main(int argc, const char * argv[]) {
DoublyLinkedList<int> intList;
int w = 5;
intList.insertFront(&w);
intList.print();
return 0;
}
makefile
#define target, its dependencies and files
doublylinkedlist: main.o doublylinkedlist.o
g++ -o doublylinkedlist main.o doublylinkedlist.o
#define how each object file is to be built
main.o: main.cpp
g++ -c main.cpp
doublylinkedlist.o: DoublyLinkedList.cpp DoublyLinkedList.hpp
g++ -c DoublyLinkedList.cpp
#clean up
clean:
rm -f doublylinkedlist *.o *~
Thanks in advance for any help with this.