It's a rather simple project which I created with sole purpose of learning how to create a Makefile. I have searched this to a reasonable extent before posting here, but could not find a solution. If I include the *.cpp files in main.cpp the program compiles fine, with no undefined references (although it still has some bugs when running, which I plan to deal with later).
main.cpp:
#include <iostream>
#include "dupqueue.h"
using std::string;
using std::cout;
using std::cin;
using std::endl;
int main()
{
DuplicateQueue<string> dqueue;
for(int i = 0; i < 10; i++)
{
string name;
cout << "Enter a name: ";
cin >> name;
dqueue.enqueue(name);
cout << endl;
}
dqueue.duplicate();
cout << "Double order:\n";
while(!dqueue.is_empty()) cout << dqueue.dequeue() << endl;
return 0;
}
dupqueue.h:
#ifndef QUEUE_H_INCLUDED
#define QUEUE_H_INCLUDED
template <class T>
class Queue
{
public:
Queue() : front(nullptr), rear(nullptr) {}
~Queue();
Queue(const Queue& q); // explicitly disallowed
Queue& operator=(const Queue& q); // explicitly disallowed
void enqueue(const T& item);
const T dequeue();
bool is_empty() const
{
return front == nullptr;
}
protected:
struct Node
{
T item;
Node * next;
Node(const T& i) : item(i), next(nullptr) {}
};
Node * front;
Node * rear;
};
template <class T>
class DuplicateQueue : public Queue<T>
{
public:
void duplicate();
};
#endif //QUEUE_H_INCLUDED
queue.cpp:
#include "dupqueue.h"
template <class T>
Queue<T>::~Queue()
{
Node * temp = front;
while(!temp)
{
front = front->next;
delete temp;
temp = front;
}
}
template <class T>
void Queue<T>::enqueue(const T& item)
{
rear->next = new Node(item);
rear = rear->next;
}
template <class T>
const T Queue<T>::dequeue()
{
const T item = front->item;
Node * temp = front;
front = front->next;
delete temp;
return item;
}
dupqueue.cpp:
#include "dupqueue.h"
template <class T>
void DuplicateQueue<T>::duplicate()
{
typename Queue<T>::Node * original_rear = Queue<T>::rear;
typename Queue<T>::Node * temp = Queue<T>::front;
while(temp != original_rear->next)
{
Queue<T>::rear->next = new typename Queue<T>::Node(temp->item);
Queue<T>::rear = Queue<T>::rear->next;
temp = temp->next;
}
}
Makefile:
main: main.o queue.o dupqueue.o
g++ -o main main.o queue.o dupqueue.o
main.o: main.cpp dupqueue.h queue.cpp dupqueue.cpp
g++ -c main.cpp
queue.o: queue.cpp dupqueue.h
g++ -c queue.cpp
dupqueue.o: dupqueue.cpp dupqueue.h
g++ -c dupqueue.cpp
clean:
rm -f main *.o
make output:
g++ -o main main.o queue.o dupqueue.o
main.o: In function `main':
main.cpp:(.text+0x83): undefined reference to `Queue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::enqueue(
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
main.cpp:(.text+0xb7): undefined reference to `DuplicateQueue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >:
:duplicate()'
main.cpp:(.text+0xf0): undefined reference to `Queue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::dequeue(
)'
main.o: In function `DuplicateQueue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::~DuplicateQueue()':
main.cpp:(.text._ZN14DuplicateQueueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEED2Ev[_ZN14DuplicateQueueINSt7__cxx1112basic_stringIcSt1
1char_traitsIcESaIcEEEED5Ev]+0x25): undefined reference to `Queue<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
> >::~Queue()'
collect2: error: ld returned 1 exit status
make: *** [Makefile:2: main] Error 1