2

I had refrenced a few other similar questions, they would often point to circularity being the problem. But I cannot see that anywhere within my code.

arrayi.cpp:

#include "arrayi.h"

// Member function definitions for class Array

// Initialize static data member at file scope
template<typename T>
int Array<T>::arrayCount = 0;   // no objects yet

// Default constructor for class Array
template<typename T>
Array<T>::Array(int arraySize)
{
    ++arrayCount;             // count one more object
    size = arraySize;         // default size is 10
    ptr = new int[size];      // create space for array
    assert(ptr != 0);  // terminate if memory not allocated
    int i;
    for (i = 0; i < size; i++)
        ptr[i] = 0;            // initialize array
}

arrayi.h:

#ifndef ARRAYI_H_
#define ARRAYI_H_

#include <iostream>
#include <cstdlib>
#include <cassert>
using namespace::std;




template<typename T> class Array;
template<typename T>
ostream &operator<< (ostream& output, const Array<T> &a);





template<typename T>
class Array
  {
    friend ostream &operator<< <>(ostream &output, const Array<T> &a);


  public:
    Array(int = 10);    //constructor
    Array(const Array &);   //copy constructor


  private:
      int *ptr; //ptr to first array element
      int size; //size of the array
      static int arrayCount;    // #of arrays instantiated
 };

#include "arrayi.t"

#endif

arrayi.t:

#ifndef ARRAYI_T_
#define ARRAYI_T_

#include <iostream>
#include <cstdlib>
#include <cassert>
using namespace::std;

// Default constructor for class Array
template<typename T>
Array<T>::Array(int arraySize)
{
cout << "calling the constructor \n";

}




// Overloaded output operator for class Array
template<typename T>
ostream &operator<<(ostream &output, const Array<T> &a)
{

  int i;
  output << "{ ";

  for (i = 0; i < a.size; i++)
    {
      output << a.ptr[i] << ' ';

      if ((i + 1) % 10 == 0)
        output << "}" << endl;
    }  //end for

  if (i % 10 != 0)
    output << "}" << endl;

  return output;   // enables cout << x << y;
}


#endif

I have been scanning my code up and down for quite some hours now, so any help would be much appreciated, thanks in advance! Any messy or broken looking code may be because this is from a work in progress, but there are no errors but the mentioned one at the moment. Everything shown compiles when the function "Array::Array(int arraySize)" is removed.

k seaner
  • 35
  • 3
  • 1
    Typically one should not place parts of a template in a CPP file ([Explanation](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file)). – user4581301 Feb 21 '19 at 22:46
  • Placing `using namespace std;` in a header is frowned on as it turns your header into a potential boobytrap. If a file includes your header it now uses namespace `std` and if you're not expecting it, inscrutable bugs can result. – user4581301 Feb 21 '19 at 22:48

1 Answers1

2

arrayi.t defines

Array<T>::Array(int arraySize)
{
cout << "calling the constructor \n";

}

arrayi.cpp defines

template<typename T>
Array<T>::Array(int arraySize)
{
    ++arrayCount;             // count one more object
    size = arraySize;         // default size is 10
    ptr = new int[size];      // create space for array
    assert(ptr != 0);  // terminate if memory not allocated
    int i;
    for (i = 0; i < size; i++)
        ptr[i] = 0;            // initialize array
}

Two definitions of the same function with the same parameters is not allowed.

Solution:

Pick the one that is the real constructor. Delete the other one. If you select the implementation in arrayi.cpp, ensure that it is visible to translation units that require it. This most likely means move it to arrayi.t.

Give Template static variable a read for heads-up on another problem coming your way.

user4581301
  • 33,082
  • 7
  • 33
  • 54