brich744
asked on
Error with seperating header files from .cpp files
Hello Everyone,
I have a program that has two classes with and both has templates. The program worked fine when I had everything in the header files. But since I have split the definition and declaration I am receiving multiple errors
PQ.h:
PQ.cpp:
StackLList.h
StackLList.cpp
Main.cpp
I have a program that has two classes with and both has templates. The program worked fine when I had everything in the header files. But since I have split the definition and declaration I am receiving multiple errors
PQ.h:
#ifndef PQ_H
#define PQ_H
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
#include"StackLList.h"
template<class Data> class ListNode;
template<class Comparable, class Data>
class PQ
{
public:
PQ();
void insert(ListNode<Data>&);
void delete_max();
void swap(ListNode<Data>&, ListNode<Data>&);
private:
vector< ListNode<Data> > vector_PQ;
int size;
};
#endif
PQ.cpp:
#include"PQ.h";
template<class Comparable, class Data>
PQ<Comparable, Data>::PQ()
:size(0)
{}
template<class Comparable, class Data>
void PQ<Comparable, Data>::insert(ListNode<Data> &x)
{
if(vector_PQ.size() == 0)
{
vector_PQ.push_back(x);
size++;
return;
}
size++;
vector_PQ.push_back(x);
int child = size-1;
int parent = (child/4);
while(vector_PQ[parent].counter < vector_PQ[child].counter)
{
swap(vector_PQ[parent], vector_PQ[child]);
child = parent;
parent = (child/4);
}
}
template<class Comparable, class Data>
void PQ<Comparable, Data>::delete_max()
{
if(vector_PQ.size() == 1)
{
vector_PQ.pop_back();
return;
}
ListNode<Data> nextItem = vector_PQ[0];
swap(vector_PQ[0], vector_PQ[size-1]);
size--;
vector_PQ.pop_back();
int parent = 0;
vector< ListNode<Data> > child_vec;
int iter = 1;
for(int i = 4; i>= 1; i--)
{
int child = (4*parent)+iter;
if(child <= vector_PQ.size() - 1)
vector_PQ[0] = vector_PQ[child];
iter--;
}
}
template<class Comparable, class Data>
void PQ<Comparable, Data>::swap(ListNode<Data>& a, ListNode<Data>& b)
{
ListNode<Data> temp;
temp = a;
a = b;
b = temp;
}
StackLList.h
#ifndef STACKLLIST_H
#define STACKLLIST_H
#include<iostream>
using namespace std;
#include"PQ.h"
template<class Data>
class ListNode
{
public:
ListNode(Data &nodeValue, int counter_value)
: value(nodeValue), next(NULL), counter(counter_value)
{}
ListNode()
:value(NULL),next(NULL), counter(0)
{}
ListNode *next;
Data value;
int counter;
};
#endif
StackLList.cpp
#include"StackLList.h"
template<class Data, class Comparable>
class StackLList
{
public:
StackLList();
~StackLList();
void push(Data&);
void pop();
bool isEmpty();
private:
ListNode<Data> *top;
PQ<Data, Comparable> *queue;
};
template<class Data, class Comparable>
StackLList<Data, Comparable>::StackLList()
{
top = NULL;
queue = new PQ<Data, Comparable>;
}
template<class Data, class Comparable>
StackLList<Data, Comparable>::~StackLList()
{
ListNode *node_ptr, *next_node;
node_ptr = top;
while(node_ptr != NULL)
{
next_node = node_ptr->next;
delete node_ptr;
node_ptr = next_node;
}
}
template<class Data, class Comparable>
void StackLList<Data, Comparable>::push(Data& data)
{
static int timeStamp = 0;
timeStamp++;
ListNode<Data> *new_node = new ListNode<Data>(data,timeStamp);
if(isEmpty())
{
top = new_node;
new_node->next = NULL;
}
else
{
new_node->next = top;
top = new_node;
}
queue->insert(*new_node);
}
template<class Data, class Comparable>
void StackLList<Data, Comparable>::pop()
{
ListNode<Data> *temp;
if(isEmpty())
cout<<"The Stack Is Empty"<<endl;
else
{
temp = top;
delete top;
top = temp;
}
queue->delete_max();
}
template<class Data, class Comparable>
bool StackLList<Data, Comparable>::isEmpty()
{
bool flag;
if(top == NULL)
flag =true;
else
flag = false;
return flag;
}
Main.cpp
#include<iostream>
#include<string>
using namespace std;
#include"StackLList.h"
int main()
{
cout<<"****************** 4-HEAP PROGRAM *******************"<<endl;
char number;
int answer = 1;
StackLList<char,char> *stack = new StackLList<char,char>;
do
{
cout<<"1) Push"<<endl;
cout<<"2) Pop"<<endl;
cout<<"3) Exit"<<endl;
cin>>answer;
if(answer == 1)
{
cout<<"Please Enter In Your Data"<<endl;
cin>>number;
stack->push(number);
}
else if(answer == 2)
stack->pop();
else
break;
}while(answer != 3);
system("PAUSE");
return 0;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Main.cpp uses StackLList<char,char>, but StackLList class is not defined in StackLList.h.
Your PQ and StackLList are co-dependent (i.e., PQ.h includes StackLList.h and vice-versa). This makes it a bit harder when dealing with templates. It would be easier if these two classes were not coupled.
Your PQ and StackLList are co-dependent (i.e., PQ.h includes StackLList.h and vice-versa). This makes it a bit harder when dealing with templates. It would be easier if these two classes were not coupled.
i would recommend you to go back to your previous header where the implementation of the templates is with the class declaration and so the compiler hasn't problems to instantiate real types with the template as explained in above comments and links.
Sara
Sara
Aren't the defintion and declaration of template classes required to be in the same file?
http://www.cplusplus.com/doc/tutorial/templates/:
http://www.cplusplus.com/doc/tutorial/templates/:
Because templates are compiled when required, this forces a restriction for multi-file projects: the implementation (definition) of a template class or function must be in the same file as its declaration. That means that we cannot separate the interface in a separate header file, and that we must include both interface and implementation in any file that uses the templates.
@evilrix
I guess I should have read your article first - that was much more useful than the cplusplus.com tutorial page.
I guess I should have read your article first - that was much more useful than the cplusplus.com tutorial page.
@tgerbert,
>> Aren't the defintion and declaration of template classes required to be in the same file?
There are ways to separate template declarations and definitions.
>> Aren't the defintion and declaration of template classes required to be in the same file?
There are ways to separate template declarations and definitions.
Yup, got that from evilrix's article - I was a little surprised cplusplu.com just outright said "It can't be done" (even if it was just a tutorial), so I gather it's just not commonly done?
@brich744
Sorry I kinda hijacked your thread a bit - I'm done asking questions. ;)
@brich744
Sorry I kinda hijacked your thread a bit - I'm done asking questions. ;)
#include "thefile.cpp"
at teh bottom of the headers for your template classes.