0

first question ever, here goes:

I've got a template class split into header and source file. At the bottom of the header file I'm including the source file and I'm using #ifndef/#define/#endif guards on the source file now. Many folks suggest to others that I should use inline to define my functions; this is a homework assignment and is not permitted.I have also read answers that indicate I should not use .cpp source files and instead use something like .tcc/.tcp so that the IDE knows they are template source files but this didn't work either.

I actually got this to work by including the source file rather than the header in my main file but I know this isn't what I'm supposed to be doing.

Articles on this site that I've read trying to solve the problem include:

Including .cpp file in the header file for a template class What is the correct file extension for a C++ template implementation file? Splitting templated C++ classes into .hpp/.cpp files--is it possible? C++ Unresolved external symbol with Class templates Why do I get "unresolved external symbol" errors when using templates?

This seems like a no-brainer problem and has been solved a hundred times, so why won't my code do it's thing? Thanks for your help gang, my code is posted below.

Header file:

    //This file contains the declarations and signatures for Array class
//members and functions. The class is used to manage memory

#ifndef ARRAY_HPP
#define ARRAY_HPP
#include "Point.hpp"                                            //the array is of points and needs the Point.hpp file

namespace DanWhite
{
    namespace Containers
    {
        template <class T> class Array
        {
        private:
            T* pointarray;  //the dynamic array itself
            int size;   //the size of the array

        public:
            Array();    //creates a dynamic array of 10 points
            Array(int arraysize);   //creates a dynamic array of <arraysize> points
            Array(const Array<T> &AnotherArray);    //creates a dynamic array exactly the same as another

            ~Array();   //destructor

            int Size() const;   //returns the size of the array
            void SetElement(int element,
                const T& point);    //sets a specific element in the array
            T GetElement(int element) const;    //returns a specific element in the array

            Array<T>& operator=(const Array<T>& source);    //sets the points of an array equal to another
            const T& operator[](int element) const; //allows reading an element in an array
            T& operator[](int element); //allows writing to an element in an array
        };
    }
}

#ifndef ARRAY_CPP
#define ARRAY_CPP
#include "Array.cpp"
#endif

#endif

Source File

    //this source file implements all of the functions and operators in the
//Array class header file

#ifndef ARRAY_CPP
#define ARRAY_CPP

#include "Point.hpp"
#include "OOBE.hpp"
#include "Array.hpp"
#include <sstream>

using namespace DanWhite::Containers;

template <class T>
Array<T>::Array() : size(10)                                        //default constructor
{
    std::cout << "Array default constructed" 
        << std::endl;
    pointarray = new T[10];
}

template <class T>
Array<T>::Array(int arraysize)                                  //specific constructor with size
{
    std::cout << "Array specific constructed" 
        << std::endl;
    size = arraysize;
    pointarray = new T[size];
}

template <class T>
Array<T>::Array(const Array<T>& anotherarray)                       //copy constructor
{
    std::cout << "Array<T> copy constructed" 
        << std::endl;

    size = anotherarray.size;

    pointarray = new T[size];

    for (int i = 0; i < anotherarray.size; i++)
    {
        pointarray[i] =  anotherarray.pointarray[i];
    }
}

template <class T>
Array<T>::~Array()                                              //destructor
{
    std::cout << "Array destructed" << std::endl;
    delete [] pointarray;
}

template <class T>
int Array<T>::Size() const                                      //returns the size of the array object
{
    return size;
}

template <class T>
void Array<T>::SetElement(int element,                          //changes an element of an array object
    const T& t)
{
    if (element > (size-1) || element < 0)
    {
        throw OOBE(element);
    }
    pointarray[element] = t;
}

template <class T>
T 
    Array<T>::GetElement(int element) const                 //returns an element of an array object
{
    if (element > (size-1) || element < 0)
    {
        throw OOBE(element);
    }
    return pointarray[element];
}

template <class T>
Array<T> & Array<T>::operator=(const Array<T> & source)             //assigns the values of one array object
                                                            //to another array object
{
    if (this == &source)
    {
        return *this;
    }

    for (int i = 0; i < source.Size(); i++)
    {
        pointarray[i] = source.pointarray[i];
    }

    return *this;
}

template <class T>
const T 
    & Array<T>::operator[](int element) const                   //returns an element of an array
{ 
    if (element > (size - 1) || element < 0)
    {
        throw OOBE(element);
    }

    else 
    {
        return pointarray[element];
    }
}

template <class T>
T & Array<T>::operator[](int element)       //allows changing an element of an array
{
    if (element > (size - 1) || element < 0)
    {
        throw OOBE(element);
    }

    else
    {
        return pointarray[element];
    }
}


#endif

Thanks again for the help. After days trying to solve this and reading articles, I'll be pretty excited to put this behind me.

14
  • 1
    Are you compiling the source file with your other source files? Commented Mar 28, 2017 at 12:35
  • Here is an additonal one to read: stackoverflow.com/questions/495021/… Commented Mar 28, 2017 at 12:36
  • What do you mean? The whole project has six or seven headers and source files each. Commented Mar 28, 2017 at 12:37
  • When you compile all the cpp files together do you also compile Array.cpp? Commented Mar 28, 2017 at 12:39
  • 1
    OK. If array.cpp is compiling that could cause this issue. When you split the template like this and you include the source file at the bottom of the header file you need to make sure that source file is not compiled. The easiest way to do that change the file type to something like .tpp so it is not even considered by the IDE. Commented Mar 28, 2017 at 12:47

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.