//Code for ArrayClass.h
#include "AbstractArray.h"
template <class DT>

class ArrayClass : virtual public AbstractArray<DT>
{
protected:
// An array of type Object will be created and paObject will be
// the address of the array.
DT* paObject;
int _size;
void copy (const ArrayClass<DT>& ac);
public:
ArrayClass ();
ArrayClass (int n);
ArrayClass (int n, const DT& val);
ArrayClass (const ArrayClass<DT>& ac);
virtual ~ArrayClass ();
virtual int size () const;
virtual DT& operator [] (int k);
void operator= (const ArrayClass<DT>& ac);
};
//Code for ArrayClass.cpp

#include "ArrayClass.h"

template <class DT>
ArrayClass<DT>::ArrayClass ()
{
	_size = 0; // default in case allocation fails
	paObject = new DT[1];
	if (paObject == NULL) throw ArrayMemoryException();
	_size = 1;
}
template <class DT>
ArrayClass<DT>::ArrayClass (int n)
{
	_size = 0; // default in case allocation fails
	paObject = new DT[n];
	if (paObject == NULL) throw ArrayMemoryException();
	_size = n;
}

template<class DT>
ArrayClass<DT>::ArrayClass (int n, const DT& val)
{
	int i;
	_size = 0; // default in case allocation fails
	paObject = new DT[n];
	if (paObject == NULL) throw ArrayMemoryException();
	_size = n;
	for (int i = 0; i < n; i++)
		paObject[i] = val;
}
template <class DT>
ArrayClass<DT>::ArrayClass (const ArrayClass<DT>& ac)
{
	copy (ac);
}

template <class DT>
int ArrayClass<DT>::size () const
{
	return _size;
}

template <class DT>
DT& ArrayClass<DT>::operator [] (int k)
{
	if ((k < 0) || (k >= size())) throw ArrayBoundsException();
	return paObject[k];
}
template <class DT>
void ArrayClass<DT>::operator= (const ArrayClass<DT>& ac)
{
	if (paObject != NULL)
		delete[] paObject;
	copy (ac);
}
template<class DT>
std::ostream& operator<< (ostream& s, AbstractArray<DT>& ac)
{
	s << "[";
	for (int i = 0; i < ac.size (); i++)
	{
		if (i > 0)
		{
			s << ',';
		}
		s << ac [i];
	}
	s << "]";
	return s;
}
template <class DT>
void ArrayClass<DT>::copy (const ArrayClass<DT>& ac)
{
	_size = 0; // default in case allocation fails
	paObject = new DT[ac._size];
	if (paObject == NULL) throw ArrayMemoryException();
	_size = ac._size;
	for (int i = 0; i < _size; i++)
	{
		paObject[i] = ac.paObject[i];
	}
}
//Code for AbstractVector.h

template <class DT>
class AbstractVector : virtual public AbstractArray<DT>
{
public:
	virtual void insert (const DT& item, int index) =
		NULL;
	//insert a new DT at position index in the vector.
	virtual void remove (int index) = NULL;
	//remove the object at position index of the vector.
	virtual void add (const DT& item) = NULL;
	// adds item at the end of the Vector
};
//Code for AbstractArray.h
#include <iostream>
using namespace std;

class Exception { };
class ArrayException : public Exception { };
class ArrayMemoryException : public ArrayException { };
class ArrayBoundsException : public ArrayException { };

template <class DT>
class AbstractArray
{
public:
virtual int size () const = NULL;
virtual DT& operator [] (int k) = NULL;
friend std::ostream& operator<< (ostream& s, AbstractArray<DT>& ac);
};