I've seen this question asked a lot on this website, but trying the solutions offered on here have yet to work with my program. So, I apologize for asking this question for the umpteenth time, but nothing is working for me.
I compile the following
g++ deque.cpp deque.h driver.cpp
and then get the error
/tmp/ccvkttRj.o: In function `main':
driver.cpp:(.text+0x20): undefined reference to `Deque<int>::Deque()'
driver.cpp:(.text+0x42): undefined reference to `Deque<int>::addBack(int const&)'
driver.cpp:(.text+0x6f): undefined reference to `Deque<int>::addFront(int const&)'
driver.cpp:(.text+0x8d): undefined reference to `Deque<int>::Deque(Deque<int> const&)'
driver.cpp:(.text+0xa7): undefined reference to `Deque<int>::addBack(int const&)'
driver.cpp:(.text+0xcf): undefined reference to `Deque<int>::isEmpty() const'
driver.cpp:(.text+0xe2): undefined reference to `Deque<int>::removeFront()'
driver.cpp:(.text+0x125): undefined reference to `Deque<int>::isEmpty() const'
driver.cpp:(.text+0x138): undefined reference to `Deque<int>::removeBack()'
driver.cpp:(.text+0x15f): undefined reference to `Deque<int>::~Deque()'
driver.cpp:(.text+0x16b): undefined reference to `Deque<int>::~Deque()'
driver.cpp:(.text+0x190): undefined reference to `Deque<int>::~Deque()'
driver.cpp:(.text+0x1a1): undefined reference to `Deque<int>::~Deque()'
collect2: error: ld returned 1 exit status
As far as I can tell, I'm using #include and #ifndef in the appropriate places, my method signatures are the same in my all my files. But I have to be wrong otherwise I wouldn't be getting this error.
Here is my program for a deque:
the header
#ifndef DEQUE_H #define DEQUE_H #include <iostream> using namespace std; template <class Object> class Deque { public: Deque(); // Constructor. Deque(const Deque &rhs); // Copy constructor. ~Deque(); // Destructor. bool isEmpty() const; // Is deque empty. int size() const; // Returns # of deque nodes. const Object &getFront() const; // Retrieve front node. const Object &getBack() const; // Retrieve tail node. void clear(); // Clears all nodes from deque. void addFront(const Object &obj); // Add a new node to the front. void addBack(const Object &obj); // Add a new node to the rear. Object removeFront(); // Remove front node. Object removeBack(); // Remove rear node. const Deque &operator=(const Deque &rhs); // Assignment. private: struct DequeNode { Object item; DequeNode *next; DequeNode *prev; }; DequeNode *front; DequeNode *back; }; #endif
the cpp
#include "deque.h" template <class Object> Deque<Object>::Deque() // Constructor. { front = back = NULL; } template <class Object> Deque<Object>::Deque(const Deque &rhs) // Copy constructor. { front = back = NULL; *this = rhs; } template <class Object> Deque<Object>::~Deque() // Destructor. { clear(); } template <class Object> bool Deque<Object>::isEmpty() const // Check if deque is empty. { return front == NULL; } template <class Object> int Deque<Object>::size() const // Returns # of nodes. { int i = 0; for (DequeNode *ptr = front; ptr != NULL; ptr = ptr->next) ++i; return i; } template <class Object> const Object &Deque<Object>::getFront() const // Retrieve front node. { if (isEmpty()) throw "empty queue"; return front->item; } template <class Object> const Object &Deque<Object>::getBack() const // Retrieve rear node. { if (isEmpty()) throw "empty queue"; return back->item; } template <class Object> void Deque<Object>::addFront(const Object &obj) // Add a new node to the front. { DequeNode *newPtr = new DequeNode; // Allocate the node in memory. newPtr->item = obj; // Insert obj. newPtr->next = front; // What once was front will become next. newPtr->prev = NULL; // Front node's prev is always NULL. if (isEmpty()) // If empty back points to the same as front. back = newPtr; else front->prev = newPtr; // The old front now points the new insert. front = newPtr; // Front now points to the new insert. } template <class Object> void Deque<Object>::addBack(const Object &obj) // Add a new node to the back. { DequeNode *newPtr = new DequeNode; // Allocate the node in memory. newPtr->item = obj; // Insert obj. newPtr->next = NULL; // The last node always points to null. newPtr->prev = back; // Inserting back, so point to what once was the last node. if (isEmpty()) // If empty front points to the same as back. front = newPtr; else back->next = newPtr; // Old back needs to point to new insert, not NULL. back = newPtr; // Back now points to the new insert. } template <class Object> Object Deque<Object>::removeFront() // Remove front node. { Object frontItem = getFront(); // Save what will be removed, so it can be returned. DequeNode *toDelete = front; // What will be deleted. if (front == back) // Only 1 item in the deque. front = back = NULL; else { front = front->next; // Move the next node up. front->prev = NULL; // Front node always points to NULL. } delete toDelete; // Goodbye what once was front; return frontItem; } template <class Object> Object Deque<Object>::removeBack() // Remove back/last node. { Object backItem = getBack(); // Save what will be removed, so it can be returned. DequeNode *toDelete = back; // What will be deleted. if (front == back) // Only 1 item in the deque. front = back = NULL; else { back = back->prev; // Move back up the list. back->next = NULL; // Last node always points to NULL. } delete toDelete; // Goodbye what once was back. return backItem; } template <class Object> const Deque<Object> &Deque<Object>::operator=(const Deque &rhs) // Assignment op. { if (this != &rhs) // Avoid self assignment. { clear(); // Not sure why clear, I'll have to come back to this. for (DequeNode *ptr = rhs.front; ptr != NULL; ptr = ptr->next) addBack(ptr->item); } return *this; }
main
#include <iostream> #include "deque.h" using namespace std; int main( ) { Deque<int> deque1; int item; for ( int j = 0; j < 5; j++ ) deque1.addBack( j ); for ( int j = 5; j < 10; j++ ) deque1.addFront( j ); Deque<int> deque2 = deque1; deque2.addBack( 10 ); cout << "deque1: " << endl; while ( !deque1.isEmpty( ) ) cout << deque1.removeFront( ) << endl; cout << "deque2: " << endl; while ( !deque2.isEmpty( ) ) cout << deque2.removeBack( ) << endl; }