问题
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.
回答1:
The problem was caused by using templates in the header .hpp and implementation .cpp files. After moving the implementation .cpp code into the header and removing the .cpp file it worked. This post helped me fix/understand the issue: c++ template and header files.
来源:https://stackoverflow.com/questions/50673352/c-xcode-ld-symbols-not-found-for-architecture-x86-64-clang-error-linker-c