捕获模板中的异常类

Catching an exception class within a template

本文关键字:异常      更新时间:2023-10-16

我在为正在创建的Stack模板使用异常类Overflow((时遇到问题。如果我定期定义类,就没有问题。如果我将类定义为模板,我就无法使对catch((的调用正常工作。我有一种感觉,这只是语法,但我一辈子都搞不清楚

#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;
}

问题出在catch(Stack::Overflow(语句中。正如我所说,如果这个类不是一个模板,那么它就可以正常工作。然而,一旦我将其定义为模板,它就不再起作用了。我尝试过各种语法,但总是从编译器中得到两组错误消息中的一组。

如果我使用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

编辑:我的意思是
如果我使用catch(Stack<double>:溢出(或其任何变体:

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

我实在想不通。有人知道吗?

重点是你应该放

class overflow;

外部

class Stack<>

因为这是一个一般的例外,而不是指定类型。

catch (const Stack<double>::Overflow & obj)
                 //^^^^^^^^ note this!

也就是说,您还必须提供类型。

还要注意,我接受该对象作为const引用,以避免复制原始Overflow对象!

顺便问一下,为什么要将Overflow作为嵌套类型?你有什么理由?我看不出有什么令人信服的理由这么做。如果你在Stack类模板之外定义它会更好。

您必须指定正在使用的模板实例化:

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";
}

如果不指定模板参数,编译器会感到困惑,因为它不知道要使用哪个类(例如Stack<int>Stack<double>?(。

附带说明:尽量避免对类型和变量使用相同的名称(本例中为StackStack(,这会使可读性和错误跟踪更加困难。