Reputation: 47
I am half way into my course.I am unable to understand the logic behind the errors I am receiving. I have already tried to counter it by using appropriate directives at the bottom of my Array.h file. I am receive the following 2 errors across all functions:
My questions are the following :
Main.cpp
#include <iostream>
#include "Point.h"
#include "Line.h"
#include "Circle.h"
#include "Array.h"
#include "ArrayException.h"
using namespace std;
using namespace udbhavAg::CAD;
using namespace udbhavAg::Container;
using namespace udbhavAg;
int main()
{
Array<Point> points(10);
return 0;
}
Array.h
#include "Point.h"
#include <cstring>
#include "ArrayException.h"
#ifndef ARRAY_H
#define ARRAY_H
//#include "Array.cpp"
namespace udbhavAg
{
namespace Container
{
template <typename T>
class Array {
private:
T *m_data;
int m_size;
public:
Array();
Array(int size);
Array(const Array &obj);
virtual ~Array();
//const Array operator= ( const Array & source);
Array<T> &operator=(const Array &source);
int Size() const;
void setElement(int index, T p);
T &getElement(int index) const;
T &operator[](int index);
const T &operator[](int index) const;
};
}
}
#ifndef Array_cpp // Must be the same name as in source file #define
#include "Array.cpp"
#endif
#endif ARRAY_H
Array.cpp
#include "Array.h"
#include "ArrayException.h"
namespace udbhavAg
{
namespace Container
{
template<typename T>
Array<T>::Array():m_size(3),m_data(new T[m_size]) {}
template<typename T>
Array<T>::Array(int size): m_size(size), m_data(new T[m_size]) {}
template<typename T>
Array<T>::~Array()
{
delete[] m_data;
cout << "Destructor called" << endl;
}
template<typename T>
Array<T>::Array(const Array &obj) {
m_size = obj.m_size;
m_data = new CAD::Point[m_size];
for (int i = 0; i < m_size; i++)
{
m_data[i] = obj.operator[](i);
}
}
template<typename T>
int Array<T>::Size() const
{
return m_size;
}
template<typename T>
T &Array<T>::getElement(int index) const
{
try
{
if (index >= m_size || index < 0)
{
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
void Array<T>::setElement(int index, T p)
{
try
{
if (index >= m_size || index < 0)
{
// OutofBoundsException error = OutofBoundsException(index);
// ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
m_data[index] = p;
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
Array<T> & Array<T>::operator=(const Array &source)
{
if(&source != this){ //edited self assignment test
if(m_size != source.m_size){//diff sized arrays
delete [] m_data; //reclaim space
m_size = source.m_size;
m_data = new CAD::Point[m_size]; //space created
}
}
for(int i=0; i<m_size; i++){
m_data[ i ] = source.m_data[i];}
return *this; //enables cascading a=b=c
}
template<typename T>
T &Array<T>::operator[](int index) {
try
{
if (index >= m_size || index < 0)
{
// OutofBoundsException error = OutofBoundsException(index);
// ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
const T &Array<T>::operator[](int index) const {
try
{
if (index >= m_size || index < 0)
{
// OutofBoundsException error = OutofBoundsException(index);
// ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
}
}
Upvotes: 0
Views: 1182
Reputation: 32586
probably because in Array.h :
#ifndef Array_cpp // Must be the same name as in source file #define #include "Array.cpp" #endif
so Array.cpp #include Array.h
whose #include Array.cpp
because Array_cpp
is not defined
Do not include source file in your header files
Out of that why in Array.h
#ifndef ARRAY_H #define ARRAY_H
is not at the beginning of the file ?
So possible exclusive solutions to solve are :
#include "Array.h"
at the beginning of Array.cpp#define Array_cpp
to be the very first line in Array.cppin both case you must not compile Array.cpp in your Makefile or equivalent nor link with it.
But the best one is to replace in Array.h
#ifndef Array_cpp // Must be the same name as in source file #define #include "Array.cpp" #endif
by the definitions from the file Array.cpp and to delete the file Array.cpp.
The template classes are special, all template methods must be defined in the header file and only in it, not in a source file also compiled as a 'normal' source file, the compiler does the stuff for you
Upvotes: 3