I'm doing a project in Repl.it with two classes that I want to use it, but it keeps throwing an error for undefined references. I'll post the files: Array.h
#include <string>
using namespace std;
template <class DataType>
class Array
{
public:
Array( int size );
Array( const Array<DataType> & ap );
~Array( );
Array<DataType> & operator =( const Array<DataType> & right );
inline DataType & operator [ ]( int index );
void changeSize( int newSize ); // will not alter values unless newSize is smaller
// than current capacity; in this case, the values
// from 0 to newSize - 1 will not be altered
inline int length( ) const; // returns the current capacity of the array
string err( ) const; // returns error message from errorCode
private:
DataType *elements; // points to the dynamic array
int capacity;
DataType dud; // returned from operator [ ] if index error occurs
int errorCode; // contains code for error if array misuse occurs
inline void deepCopy( const Array<DataType> & original );
};
Array.cpp
#include "Array.h"
template <class DataType>
Array<DataType>::Array( int size )
{
if ( size < 1 ) {
capacity = 1;
errorCode = 1; // nonpositive size
}
else {
capacity = size;
errorCode = 0; // no error
}
elements = new DataType [capacity];
}
template <class DataType>
Array<DataType>::Array( const Array<DataType> & ap )
{
deepCopy( ap );
}
template <class DataType>
Array<DataType>::~Array( )
{
delete [ ] elements;
}
template <class DataType>
Array<DataType> & Array<DataType>::operator =( const Array<DataType> & right )
{
if ( this == &right )
return *this;
delete [ ] elements;
deepCopy( right );
return *this;
}
template <class DataType>
inline DataType & Array<DataType>::operator [ ]( int index )
{
#ifdef DEBUG_ARRAY
if ( index < 0 || index >= capacity ) {
errorCode |= 2; // invalid index
return dud;
}
#endif
return elements[ index ];
}
template <class DataType>
void Array<DataType>::changeSize( int newSize )
{
if ( newSize < 1 )
{
errorCode |= 4; // nonpositive new size
return;
}
DataType *newArray = new DataType [newSize];
int limit = (newSize > capacity)? capacity : newSize;
for ( int i = 0; i < limit; i++ )
newArray[ i ] = elements[ i ];
delete [ ] elements;
elements = newArray;
capacity = newSize;
}
template <class DataType>
inline int Array<DataType>::length( ) const
{
return capacity;
}
template <class DataType>
string Array<DataType>::err( ) const
{
if ( errorCode == 0 )
return "No error.\n";
string errorMessage = "";
if ( errorCode & 1 ) { // nonpositive size
errorMessage += "Nonpositive size passed into constructor, so\n";
errorMessage += "the capacity was set to 1 by default.\n";
}
if ( errorCode & 2 ) // invalid index
errorMessage += "Index out of range.\n";
if ( errorCode & 4 ) { // nonpositive new size in changeSize
errorMessage += "Nonpositive size passed into changeSize, so\n";
errorMessage += "the size of the array was not changed.\n";
}
return errorMessage;
}
template <class DataType>
inline void Array<DataType>::deepCopy( const Array<DataType> & original )
{
capacity = original.capacity;
errorCode = original.errorCode;
elements = new DataType [capacity];
for ( int i = 0; i < capacity; i++ )
elements[ i ] = original.elements[ i ];
}
Stack.h
#include "Array.h"
template <class DataType>
class Stack
{
public:
Stack();
void push( DataType elementToPush );
bool pop( DataType & poppedElement );
bool peek( DataType & topElement );
bool isEmpty( ) const;
void makeEmpty( );
private:
Array<DataType> elements;
int top;
};
Stack.cpp
#include "Stack.h"
template <class DataType>
Stack<DataType>::Stack( )
: elements( 2 ), top( -1 )
{
}
template <class DataType>
void Stack<DataType>::push( DataType elementToPush )
{
if ( ++top == elements.length( ) )
elements.changeSize( elements.length( ) << 1 );
elements[ top ] = elementToPush;
}
template <class DataType>
bool Stack<DataType>::pop( DataType & poppedElement )
{
if ( top == -1 )
return false;
poppedElement = elements[ top ];
top--;
int trysize = elements.length( );
while ( ( top + 1 <= trysize >> 2 ) && trysize > 2 )
trysize >>= 1;
if ( trysize < elements.length( ) ) {
try {
elements.changeSize( trysize );
}
catch( ... ) { }
}
return true;
}
template <class DataType>
bool Stack<DataType>::peek( DataType & topElement )
{
if ( top == -1 )
return false;
topElement = elements[ top ];
return true;
}
template <class DataType>
bool Stack<DataType>::isEmpty( ) const
{
return top == -1;
}
template <class DataType>
void Stack<DataType>::makeEmpty( )
{
top = -1;
try {
elements.changeSize( 2 );
}
catch( ... ) { }
}
Main.cpp (test file)
#include <iostream>
#include "Stack.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
Stack<string> *stack = new Stack<string>();
stack->push("std::string");
std::cout << stack.isEmpty();
stack.makeEmpty();
std::cout << stack.isEmpty();
return 0;
}
The error that is throwing is:
/nix/store/v8imx1nvyz0hgvx9cbcmh6gp4ngw3ffj-binutils-2.35.1/bin/ld: ./main.o: in function
main': /home/runner/jorgeihp97/main.cpp:8: undefined reference to
Stack<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >::Stack()' /nix/store/v8imx1nvyz0hgvx9cbcmh6gp4ngw3ffj-binutils-2.35.1/bin/ld: /home/runner/jorgeihp97/main.cpp:9: undefined reference to `Stack<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >::push(std::__cxx11::basic_string<char, std::char_traits, std::allocator >)' clang-12: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [Makefile:8: main] Error 1 exit status 2
This test class is supposed to check some methods from Stack class.