создание классов исключений, которые наследуются от классов io в C ++

0

Пожалуйста, простите мою C++ наивность

Я думал о создании классов исключений, которые наследовали бы от std :: stringstream, чтобы я мог использовать оператор stringstreams << для создания текстовых сообщений об ошибках и в то же время попытаться поймать исключения по типу.

Мой код - это что-то вроде

class ExceptionXYZ : public std::stringstream
{};

Void someFunction()
{
   try
   {
      //do something
   }
   catch(const ExceptionXYZ& e)
   {
      //handle XYZ
   }

К сожалению, моему компилятору VS2008 это не нравится, и жалуется, что

ошибка C2248: 'std :: basic_ios <_Elem, _Traits> :: basic_ios': не может получить доступ к закрытому члену, объявленному в классе 'std :: basic_ios <_Elem, _Traits>'

basic_ios - отличный прародитель (или около того) строкового потока, и там должно быть какое-то неявное нарушение прав доступа, но между моим чрезвычайно ржавым C++ и компилятором бесполезное сообщение об ошибке (это не говорит мне, что частный член его беспокоит) Im немного потерял.

Я полагаю, что люди все время делают такие вещи (т.е. Бросают исключения с текстом, который нужно поймать по типу).

Помощь будет принята с благодарностью

  • 0
    Я не могу понять, почему вы хотели бы сделать это. Можете ли вы объяснить свой вариант использования?
  • 0
    На какой строке происходит ошибка?
Теги:
templates
exception
inheritance
stringstream

3 ответа

0
Лучший ответ

Вы не можете использовать std::stringstream в качестве базового класса для исключения, потому что вы не можете копировать или перемещать stringstream (из-за streambuffer внутри, если вы посмотрите на сообщение об ошибке), и это требование для объекта, который нужно выбросить. Поэтому, когда я делаю такой код, он не может скомпилироваться:

class ExceptionXYZ : public std::stringstream {};

void test_except() throw (ExceptionXYZ)
{
  ExceptionXYZ xyz;

  xyz << "This exception is useless";
  throw xyz;
}

http://ideone.com/NQUunh

1

Вы не должны наследовать классы потоков, чтобы использовать их во время построения. Если вам действительно нужно создать сообщение об ошибке, вы можете скорее сохранить информацию, необходимую для ее сборки по запросу, или построить ее при построении.

Из звуков этого вы хотите сделать что-то вроде этого:

throw ExceptionXYZ() << "some " << information << " or " << other;

Это не будет работать слишком хорошо, потому что operator<<() будет возвращать std::ostream& а не объект исключения, который вы хотите.

0

(Большинство) в STD предназначены для того, чтобы не использоваться в качестве базовых классов. Используйте их только как переменные-члены.

Чтобы дать сообщение своему исключению, вы можете сделать что-то вроде этого:

class ExceptionXYZ
{
public:
   ExceptionXYZ(const std::string& msg) : msg_(msg) {}
   const std::string& get_message() const { return msg_; }
private:
   std::string msg_;
};

std::stringstream ss;
ss << "Error " << 42;
throw ExceptionXYZ(ss.str());
  • 0
    На самом деле в стандартной библиотеке C ++ есть пара классов, которые должны быть получены из (например, std::streambuf и различные аспекты). Класс std::istream и std::ostream также предназначены для использования в качестве базовых классов, хотя только для потоков, инициализирующих свою соответствующую базу и содержащих необходимые объекты (например, std::filebuf или std::stringbuf ).
  • 0
    Никогда не говори никогда;) Я изменил его на «большинство». Например, в вашем дизайне есть что-то подозрительное, если вы используете vector , list , map или set в качестве базового класса ...
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню