I'm having a problem using the exception class Overflow() for a Stack template I'm creating. If I def开发者_如何转开发ine the class regularly there is no problem. If I define the class as a template, I cannot make my call to catch() work properly. I have a feeling it's simply syntax, but I can't figure it out for the life of me.
#include<iostream>
#include<exception>
using namespace std;
template <class T>
class Stack
{
private:
T *stackArray;
int size;
int top;
public:
Stack(int size) { this->size = size; stackArray = new T[size]; top = 0; }
~Stack() { delete[] stackArray; }
void push(T value)
{
if (isFull())
throw Overflow();
stackArray[top] = value;
top++;
}
bool isFull()
{
if (top == size)
return true;
else
return false;
}
class Overflow {};
};
int main()
{
try
{
Stack<double> Stack(5);
Stack.push( 5.0);
Stack.push(10.1);
Stack.push(15.2);
Stack.push(20.3);
Stack.push(25.4);
Stack.push(30.5);
}
catch (Stack::Overflow)
{
cout << "ERROR! The stack is full.\n";
}
return 0;
}
The problem is in the catch (Stack::Overflow) statement. As I said, if the class is not a template, this works just fine. However, once I define it as a template, this ceases to work. I've tried all sorts of syntaxes, but I always get one of two sets of error messages from the compiler.
If I use catch(Stack::Overflow):
ch18pr01.cpp(89) : error C2955: 'Stack' : use of class template requires template argument list
ch18pr01.cpp(13) : see declaration of 'Stack'
ch18pr01.cpp(89) : error C2955: 'Stack' : use of class template requires template argument list
ch18pr01.cpp(13) : see declaration of 'Stack'
ch18pr01.cpp(89) : error C2316: 'Stack<T>::Overflow' : cannot be caught as the destructor and/or copy constructor are inaccessible
EDIT: I meant
If I use catch(Stack<double>::Overflow) or any variety thereof:ch18pr01.cpp(89) : error C2061: syntax error : identifier 'Stack'
ch18pr01.cpp(89) : error C2310: catch handlers must specify one type
ch18pr01.cpp(95) : error C2317: 'try' block starting on line '75' has no catch handlers
I simply can not figure this out. Does anyone have any idea?
The point is you should put
class overflow;
outside
class Stack<>
since it is a general exception, not type specified.
catch (const Stack<double>::Overflow & obj)
//^^^^^^^^ note this!
That is, you've to provide the type also.
Also note that I'm accepting the object as const
reference so as to avoid copy of the original Overflow
object!
By the way, why did you make Overflow
a nested type? What rationale do you have? I don't see any compelling reason to do so. It would be better if you define it outside Stack
class template.
You have to specify, which template instantiation you are using:
try
{
Stack<double> Stack(5);
Stack.push( 5.0);
Stack.push(10.1);
Stack.push(15.2);
Stack.push(20.3);
Stack.push(25.4);
Stack.push(30.5);
}
catch (Stack<double>::Overflow)
{
cout << "ERROR! The stack is full.\n";
}
If you do not specify the template argument, the compiler is confused because it doesn't know which class to use (for example Stack<int>
or Stack<double>
?).
Side note: Try to avoid using same names for types and variables (Stack
and Stack
in this example), it makes the readability and bug tracking harder.
精彩评论