Это хорошая идея, чтобы определить исключение с шаблоном? - PullRequest
4 голосов
/ 20 января 2009

Я думаю, что это хорошая идея, чтобы определить исключение с помощью шаблона. Определение различных типов исключений является очень многословной задачей. Вы должны унаследовать исключение, ничего не изменилось, просто наследовать. Как это ..

class FooException : public BaseException {
public:
    ...
};

class BarException : public BaseException {
public:
    ...
};

...

Это кошмар, не правда ли? Поэтому я рассматриваю возможность определения другого исключения с помощью шаблона

/**
    @brief Exception of radio
**/
class Exception : public runtime_error {
private:
    /// Name of file that throw
    const string m_FileName;

    /// Line number of file that throw
    size_t m_Line;
public:
    Exception(const string &what, const string &File, size_t Line)
throw()
        : runtime_error(what),
        m_FileName(File),
        m_Line(Line)
    {}

    virtual ~Exception() throw() {}

    /**
        @brief Get name of file that throw
        @return Name of file that throw
    **/
    virtual const string getFileName() const throw() {
        return m_FileName;
    }

    /**
        @brief Get throw exception line
        @return Throw exception line
    **/
    virtual size_t getLine() const throw() {
        return m_Line;
    }

    /**
        @brief Get description of this exception
        @return Description of this exception
    **/
    virtual const string getMessage() const throw() {
        return what();
    }

    virtual void print(ostream &stream = cerr) const throw() {
        stream << "# RunTimeError #" << endl;
        stream << "Error : " << what() << endl;
        stream << "File : " << getFileName() << endl;
        stream << "Line : " << getLine() << endl;
    }
};


/**
    @brief Template exception of radio
**/
template <typename T>
class TemplateException : public Exception {
public:
    TemplateException (const string &what, const string &File, size_t
Line) throw()
        : Exception(what, File, Line)
    {}

    virtual ~TemplateException () throw() {}
};

}

#define THROW(type, error) (throw TemplateRadioException<type>(
(error), __FILE__, __LINE__))

Так что, если мне нужно определить новое исключение, я могу просто определить пустой класс следующим образом.

class NuclearException {};

Чтобы бросить исключение

THROW(NuclearException , "Boom!!");

Чтобы поймать

try {

} catch (TemplateException<NuclearException> &e) {
    // ...
}

Если мы хотим перехватить все исключения, мы можем написать это

try {

} catch (Exception &e) {
   // ...
}

Работает нормально, но я не уверен, что есть побочные эффекты? Это хорошая идея, чтобы определить другой тип исключения? Или есть лучшее решение? Понятия не имею: S

Спасибо. Виктор Лин.

Ответы [ 3 ]

3 голосов
/ 21 января 2009

Это интересная идея, но, помимо уже отмеченных недостатков, она также не позволит вам определить иерархию исключений: предположим, что вы хотите определить

class InvalidArgumentException {};
class NullPointerException : public InvalidArgumentException {};

тогда TemplatedException не наследуется от TemplatedException , и ваш механизм обработки исключений может оказаться более неуклюжим, чем "простой".

2 голосов
/ 20 января 2009

Если вы ленивы и не хотите писать, что нужно для объявления нового класса исключений, вы всегда можете использовать макрос, который сделает это за вас.

2 голосов
/ 20 января 2009

Это определенно возможно и отлично работает, но я бы этого не делал. Это заслоняет диагностику. GCC отобразит имя типа исключения с включенным обычным шаблоном. Я бы лично уделил несколько минут определению нового класса исключений. Это не так, как если бы ты делал это постоянно.

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