As of today, I have been working on a list class template for a week. For whatever reason, I cannot get the "List.h" and the "List.cpp" file to play nicely with each other. I'm not looking for help with any of the member functions, I just want this to start compiling. Currently, when I try to compile it, it generates the error list below:
#ifndef LIST_H
#define LIST_H
#include <iostream>
#include <iomanip>
usingnamespace std;
template <class Type>
class List
{
public:
List(); //Default constructor, 0 size array
List(int sz); //Constructor create array of size sz
//The big three
List(const List &rhs); //Copy constructor
List& operator=(const List &rhs); //Assignment operator
~List(); //Destructor
void create(int sz); //Removes the existing array and makes a new
//one of size sz.
void clear(); //Removes the array space
int getSize() const; //Returns the number of entries in the array
bool setElement(int loc, Type value); //If loc valid, assigns value at index loc and
//Returns true, otherwise return false
bool getElement(int loc, Type &value) const; //If loc valid, assign value from there and
//return true, otherwise return false
bool append(Type value); //Adds an element at after the existing elements and
//increases the number of elements, if the array if full
//it returns false
void sort(); //sorts the list in ascending order
private:
Type *list; //Pointer to array
int size; //Physical size of the array
int numElements; //Number of entries in the array
bool isValid(int loc) const; //Private function used to make sure the loc is between
//0 and numElements-1
};
template <class Type>
ostream &operator<<(ostream &stream, const List<Type> &alist);
#include "List.cpp"
#endif
template <class Type>
List<Type>::List()
{
size = 0;
numElements = 0;
list = NULL;
}
template <class Type>
List<Type>::List(int sz) //Constructor creates array
{
numElements = 0;
size = sz;
list = new Type[sz];
}
template <class Type>
List<Type>::List(const List<Type> &rhs)
{
//create a list the same size
list = new Type [rhs.size];
size = rhs.size;
numElements = rhs.numElements;
//copy the elements
for (int i=0; i<numElements; i++)
list[i] = rhs.list[i];
}
template <class Type>
List<Type> &List<Type>::operator=(const List<Type> &rhs)
{
if (&rhs != this)
{
clear();
//create a list the same size
list = new Type [rhs.size];
size = rhs.size;
numElements = rhs.numElements;
//copy the values
for (int i=0; i<numElements; i++)
list[i] = rhs.list[i];
}
return *this;
}
template <class Type>
List<Type>::~List() //Destructor
{
clear();
}
//Create
//Gets rid of the current list and create a new list
//of size sz
template <class Type>
void List<Type>::create(int sz)
{
//Gets rid of the current list
clear();
//Creates a new list
size = sz;
list = new Type [sz];
}
//getSize
//Returns the number of entries in the array
template <class Type>
int List<Type>::getSize() const
{
return numElements;
}
//append
//Appends value to the next available slot in list and returns true
//if the list is full, the value is not appended and the function
//returns false
template <class Type>
bool List<Type>::append(Type value)
{
//if the list isn't full, it throws value into the list
if(numElements != size)
{
list[numElements+1] = value;
numElements++;
returntrue;
}
//if the list is full
elsereturnfalse;
}
template <class Type>
void List<Type>::clear() //Removes the array
{
numElements = 0;
delete [] list;
list = NULL;
}
template <class Type>
bool List<Type>::setElement(int loc, Type value) //Assigns value at index loc
{
if (isValid(loc))
{
list[loc] = value;
returntrue;
}
elsereturnfalse;
}
template <class Type>
bool List<Type>::getElement(int loc, Type &value) const //assigns value the number at loc
{
if (isValid(loc))
{
value = list[loc];
returntrue;
}
elsereturnfalse;
}
template <class Type>
void List<Type>::sort() //sorts in ascending order
{
int small, i, j;
Type temp;
for (i=0; i<numElements-1; i++)
{
small = i;
for (j=i+1; j<numElements; j++)
{
if (list[j] < list[small])
small = j;
}
temp = list[i];
list[i] = list[small];
list[small] = temp;
}
}
template <class Type>
bool List<Type>::isValid(int loc) const //Private function used to make sure the loc if in range
{
return (loc >= 0 && loc < numElements);
}
template <class Type>
ostream &operator<<(ostream &stream, const List<Type> &alist)
{
Type number;
for (int j=0; j<alist.getSize(); j++)
{
stream << "[" << j << "]" << setw(5);
alist.getElement(j, number);
stream << number << endl;
}
stream << endl;
}
Sorry for the long post, but I did not want to leave anything out.
What's happening is List.cpp is being compiled on its own, and it's not #including List.h, so the compiler doesn't know wtf List is.
Change List.cpp to List.hpp or something. Make it a header. Don't compile it.
Or, have List.cpp #include List.h (but that would just unnecessarily increase compile time) -- also this approach would require you put guards on List.cpp (the whole #ifndef thing) otherwise List.cpp would #include itself and you'd have duplicate function bodies.
Also, this is unrelated, but your << operator should have return stream; at the end.