Существует проблема с тем, как вы ловите исключения. В частности, рассмотрим этот код:
struct Base
{
virtual void do() { std::cout << "Base!" << std::endl; }
};
struct Derived : Base
{
virtual void do() { std::cout << "Derived!" << std::endl; }
};
void foo(Base x)
{
x.do();
}
int main()
{
Derived d;
foo(d); // <--
}
В этой отмеченной строке d
получает то, что называется "нарезанным". То есть для того, чтобы быть Base
, все, что не является частью Base
, отсекается! Таким образом, приведенный выше код выведет «Base!».
Если нам нужен предполагаемый вывод, нам нужно сделать параметр не значением:
void foo(Base& x) // polymorphic
{
x.do();
}
Наш приведенный выше код будет отображать «Derived!», Потому что он больше не будет нарезан. (Можно также использовать указатель.)
Итак, взгляните на ваше предложение catch:
catch (exception e)
Здесь любые исключения, которые вы выбросили, будут нарезаны в базовый класс std::exception
, теряя всю производную информацию! Вот почему гораздо чаще (и, возможно, «правильно») отлавливать по ссылке:
catch (const exception& e)
Теперь вы обнаружите, что e.what()
возвращает сообщение об ошибке без нарезки, как и предполагалось.
Старый
Вот как должна выглядеть вся вещь (не используйте using namespace
в заголовке!):
// rpn_expression_error.h
#include <stdexcept> // for logic_error
#include <string> // for string
class rpn_expression_error : public std::logic_error
{
public:
explicit rpn_expression_error(const std::string& pMsg);
};
// rpn_expression_error.cpp
#include "rpn_expression_error.h"
rpn_expression_error::rpn_expression_error(const std::string& pMsg) :
std::logic_error(pMsg)
{}
Старые
Потому что эти классы исключений объявлены в стандартном пространстве имен, а ваши нет. string
находится внутри пространства имен std
, поэтому им не нужно его квалифицировать, но вы делаете:
#include <string>
// ...
vvv
explicit rpn_expression_error(const std::string& arg);
Помните, что я изменил имя вашего параметра. Имена, содержащие двойное подчеркивание, зарезервированы, и вы не должны их использовать.