Hey everyone I am having trouble understanding proper syntax for template class, I am trying to convert a regular class to template class but am at a dead end. I am trying to take it one part at a time, the first is the declaration in main.cpp, FiniteClass<int> s1(5); returns linker errors when I attempt to compile. The declarration in finite.h FiniteStack(int size); and in FiniteStack.cpp FiniteClass::FiniteClass<C>(int size); are what correspond with each other.

finitestack.h

Code:
#ifndef FINITESTACK_H
#define FINITESTACK_H

//class  IntFiniteStack {
template <class C> 
class FiniteStack {
  private:
   // int* items;
	 C* items; 
   // int size; // array size (capacity of stack)
	 int size; 
    //int top;
	 int  top; 
  public:
    class StackEmptyException{ }; // empty inner class for exception handling
    class StackFullException{ }; // empty inner class for exception handling
    //IntFiniteStack();
	FiniteStack();
    //IntFiniteStack(int size);
	FiniteStack(int size); 
    virtual ~FiniteStack();
    void push(int) ;
    int pop();
    bool isEmpty();
    bool isFull();
};

#endif
finitestack.cpp

Code:
#include "FiniteStack.h"
template <class C>
FiniteStack<C>::FiniteStack() {
  top = 0;
  size = 10;
  items = new int[10]; //default size
}
template <class C> 
FiniteStack<C>::FiniteStack(int size) {
  top = 0;
  this->size = size;
  items = new int[size];
}

// destructor: free all the memory allocated for the stack
template <class C> 
FiniteStack<C>::~FiniteStack() {
  delete [] items;
}

// push a data onto the stack
template <class C>
void FiniteStack<C>::push(int data) {
  if (isFull())
    throw StackFullException();
  items[top] = data;
  top++; // to combine two lines ==> items[top++] = data
}

// pop the data from the stack
template <class C>
int FiniteStack<C>::pop() {
  if (isEmpty())
    throw StackEmptyException();
  --top;
  return items[top]; // to combine two lines ==> return items[--top];
}

// is stack empty?
template <class C> 
bool FiniteStack<C>::isEmpty() {
  if (top == 0) return true;
  else return false;
}

// is stack full?
template <class C> 
bool FiniteStack<C>::isFull() {
  if (top == size) return true;
  else return false;
}
main.cpp

Code:
#include <iostream>
using namespace std;

#include "FiniteStack.h"

int main() {
	FiniteStack<int> s1(5);
  //FiniteStack<int> s1(5);
 /*
  // Stack empty test
  if (s1.isEmpty()) {
      cout << "s1 is empty at the beginning." << endl;
  } else {
      cout << "s1 must be empty. Something's wrong!" << endl;
  }
  
    s1.push(1);
    s1.push(2);	
    s1.push(3);
    s1.push(4);
    s1.push(5);
  
  // Stack full test
  if (s1.isFull()) {
      cout << "s1 is full after five push() calls." << endl;
  } else {
      cout << "s1 must be full. Something's wrong!" << endl;
  }
  
  // pop() test: reverses the items
  cout << "Expected: 5 4 3 2 1 -->" << endl;
  for (int i = 0; i < 5; i++) {
      cout << s1.pop() << endl;
  }
  
  // Stack empty test
  if (s1.isEmpty()) {
      cout << "s1 is empty after five pop() calls." << endl;
  } else {
      cout << "s1 must be full. Something's wrong!" << endl;
  }

  // StackFullException test
  cout << "Expected: StackFullException --> ";
  try {
    s1.push(1);
    s1.push(2);
    s1.push(3);
    s1.push(4);
    s1.push(5);
    s1.push(6);
  } catch (FiniteStack::StackEmptyException) {
    cout << "Exception: cannot pop, stack is empty" << endl;
  } catch (FiniteStack<StackFullException>) {
    cout << "Exception: cannot push, stack is full" << endl;
  }
  
  // StackEmptyException test
  cout << "Expected: StackEmptyException --> ";
  try {
    s1.pop(); s1.pop(); s1.pop(); s1.pop(); s1.pop(); s1.pop();

  } catch (FiniteStack::StackEmptyException) {
    cout << "Exception: cannot pop, stack is empty" << endl;
  } catch (FiniteStack<C>::StackFullException) {
    cout << "Exception: cannot push, stack is full" << endl;
  }*/
  
  return 0;

}