C++ Standard to Template Class
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;
}
Re: C++ Standard to Template Class
C++ FAQ Lite 35.7. Why can't I separate the definition of my templates class from it's declaration and put it inside a .cpp file?
Also:
- You should put a "using namespace" declaration below all includes, otherwise it can cause name conflicts in the included files.
- You should derive you exceptions from std::exception, such that they can be caught by someone who doesn't know your code.
- Your class is not const-correct. Member functions such as isEmpty and isFull should be const.
Re: C++ Standard to Template Class
Also, your template class cannot be copied safely.
Code:
int main()
{
FiniteStack<int> s1;
FiniteStack<int> s2 = s1;
FiniteStack<int> s3;
s3 = s1;
}
This simple program creates a memory leak and a double free error when the program exits -- even if you got your original code to compile and work for your main() function, the main() function I wrote above breaks everything.
Your class lacks a user-defined copy constructor and assignment operator to handle the dynamically allocated memory properly when making copies.
If the class cannot be copied, then you must make the copy constructor and assignment operator private functions, and both without implementations.
Regards,
Paul McKenzie
Re: C++ Standard to Template Class
Quote:
Originally Posted by
D_Drmmr
Also:
- You should put a "using namespace" declaration below all includes, otherwise it can cause name conflicts in the included files.
I'll just add that this, of course, is when you are inside a .cpp.
"using namespace" has no place anywhere in a .h file.
Re: C++ Standard to Template Class
Code:
void push(int)
int pop();
Why "int" if you want to push/pop objects of class C?
Re: C++ Standard to Template Class
Quote:
Originally Posted by
monarch_dodra
I'll just add that this, of course, is when you are inside a .cpp.
"using namespace" has no place anywhere in a .h file.
Not entirely true. It's fine so long as it's used in a restricted scope.