Hello! I was creating a custom array class as an exercise in my exploring of class and function templates.
Here's my header file:
#include <iostream>
template <typename el>
class Array
{
friend std::ostream &operator<<(std::ostream&,const Array&);
friend std::istream &operator>>(std::istream&,Array&);
public:
Array(const int& arraySize=0); //set all members of array with size arraySize to NULL
Array(const Array&);
~Array(); //destructor
size_t getSize() const; //return size
const Array &operator=(const Array&);
bool operator==(const Array&) const;
bool operator!=(const Array&) const;
el &operator[](int); //returns modifiable lvalue
el operator[](int) const; //returns non-modifiable rvalue
private:
size_t size; //ptr-based array size
el* ptr;
};
After I created the header file, I created the .cpp
file, and I defined my class in it.
After I compiled this (please keep in mind that I did not import my header file into main, I did not get any error compiling).
However, when I imported the header file into main... I got errors linking the functions of the Array class that were called.
Here's my definition of the class in the .cpp file:
// TemplatedArray class definition
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include "TemplatedArray.h"
using namespace std;
//default constructor for class Array
template <typename el>
Array<el>::Array(const int& arraySize):
size(arraySize > 0 ? arraySize : throw invalid_argument("Array size must be greater than 0")),ptr(new el[size])
{
for (size_t i=0; i < size; ++i)
ptr[i]=NULL; //undefined value
}
template<typename el>
Array<el>::Array(const Array<el>& arrayToCopy):size(arrayToCopy.size),ptr(new el[size])
{
for (size_t i=0; i < size; ++i)
//copy each member of arrayToCopy into object
ptr[i]=arrayToCopy.ptr[i];
}
template<typename el>
Array<el>::~Array<el>()
{
delete [] ptr;
}
//return member of elements of array
template<typename el>
size_t Array<el>::getSize() const
{
return size;
}
template<typename el>
const Array<el>& Array<el>::operator=(const Array<el> &right)
{
if (right != this) //avoid self-assignment
{
//for arrays of different sizes, deallocate original
//left-side Array, then allocate new left-size Array
if (size != right.size)
{
delete [] ptr;
size=right.size;
ptr=new el[size];
}
for (size_t i=0; i < size; ++i)
ptr[i]=right.ptr[i];
}
}
//determine if two Arrays are equal and return true, otherwise return false
template<typename el>
bool Array<el>::operator==(const Array<el>& right) const
{
if (size != right.size)
return false;
for (size_t i=0; i < size; i++)
if (ptr[i] != right.ptr[i])
return false; //Array contents not equal
return true; //Array contents are equal
}
//determine if two Arrays are not equal, and return true, otherwise return false
template<typename el>
bool Array<el>::operator!=(const Array<el>& right) const
{
return !(this == right);
}
//return modifiable lvalue
template<typename el>
el& Array<el>::operator[](int subscript)
{
//check for out-of-range error
if (subscript < 0 || subscript >=0)
throw out_of_range("Subscript out of range");
return ptr[subscript];
}
//overloaded subscript operator for const Arrays
//const reference return creates an rvalue
template<typename el>
el Array<el>::operator[](int subscript) const
{
if (subscript < 0 || subscript >= size)
throw out_of_range("Subscript out of range");
return ptr[subscript]; //returns copy of the element
}
//overloaded input iterator for class Array
//inputs values for entire array
template<typename el>
istream &operator>>(istream& input,const Array<el>& a)
{
//output private ptr-based array
for (size_t i=0; i < a.size; i++)
input >> a.ptr[i];
return input; //enable cin >> x >> y
}
//overloaded output operator for class Array
template<typename el>
ostream &operator<<(ostream &output,const Array<el>& a)
{
//output private ptr-based array
for (size_t i=0; i < a.size; i++)
{
output << setw(12) << a.ptr[i];
if ((i+1)%4 == 0) //four numbers per row of output
output << endl;
}
if (a.size%4 != 0) //end last line of output
output << endl;
return output;
}
What am I doing wrong? Am I making a mistake in declaring the typename el each time before I define the class functions and the inputstream and outputstream operators?