Перехват класса исключений в шаблоне - PullRequest
3 голосов
/ 07 апреля 2011

У меня проблема с использованием класса исключения 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 :: Overflow) или любой их вариант:

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

Я просто не могу понять это.У кого-нибудь есть идеи?

Ответы [ 3 ]

2 голосов
/ 07 апреля 2011

Дело в том, что вы должны поставить

class overflow;

за пределами

class Stack<>

, поскольку это общее исключение, а не тип.

2 голосов
/ 07 апреля 2011
catch (const Stack<double>::Overflow & obj)
                 //^^^^^^^^ note this!

То есть вы также должны указать тип.

Также обратите внимание, что я принимаю объект как ссылку const, чтобы избежать копирования оригинального Overflow объекта!

Кстати, почему вы сделали Overflow вложенным типом? Какое у вас обоснование? Я не вижу веских причин для этого. Было бы лучше, если бы вы определили его вне Stack шаблона класса.

1 голос
/ 07 апреля 2011

Вы должны указать, какой экземпляр шаблона вы используете:

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>?).

Примечание: старайтесь не использовать одинаковые имена для типов и переменных (в данном примере Stack и Stack), это затрудняет чтение и отслеживание ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...