Frequently Asked Questions
What is the cost of calling boost::throw_exception?
Стоимость этого повышения:исключениедобавляется в качестве основания исключения, испускаемого импульсом::throw_исключение(за исключением тех случаев, когда пройденный тип уже происходит от ускорения):Исключение.
Вызов импульса:бросок_исключениене вызывает выделения динамической памяти.
What is the cost of BOOST_THROW_EXCEPTION?
В дополнение к вызывающему ускорению::бросок_исключение,BOOST_THROW_EXCEPTIONвызывает __FILE__, __LINE__ иBOOST_THROW_EXCEPTION_CURRENT_FUNCTIONМакрос. Пространство, необходимое для хранения информации, уже включено в размер (буст::исключение).
ВызовBOOST_THROW_EXCEPTIONне вызывает выделения динамической памяти.
Should I use boost::throw_exception or BOOST_THROW_EXCEPTION or just throw?
Преимущество вызова импульса:бросок_исключениевместо непосредственного использования бросок заключается в том, что он гарантирует, что испускаемое исключение происходит от импульса::исключениеи что он совместим с импульсом::ток_исключение.
МакроBOOST_THROW_EXCEPTIONтакже приводит к призыву к увеличению::бросок_исключение, но в дополнение к этому он записывает в объекте исключения __FILE__ и __LINE__ броска, а также красивое название функции, которая бросает. Это позволяет повысить:диагностическая_информациядля составления более полезного, если не удобного для пользователя сообщения.
Типичное использование бустера:диагностические_информация:
catch(...)
{
std::cerr <<
"Unexpected exception, diagnostic information follows:\n" <<
current_exception_diagnostic_information();
}
Это возможное сообщение, которое он может отобразить - информация в первой строке доступна только в том случае, еслиBOOST_THROW_EXCEPTIONиспользовался для метания:
example_io.cpp(70): Throw in function class boost::shared_ptr<struct _iobuf> __cdecl my_fopen(const char *,const char *)
Dynamic exception type: class boost::exception_detail::clone_impl<class fopen_error>
std::exception::what: example_io error
[struct boost::errinfo_api_function_ *] = fopen
[struct boost::errinfo_errno_ *] = 2, "No such file or directory"
[struct boost::errinfo_file_name_ *] = tmp1.txt
[struct boost::errinfo_file_open_mode_ *] = rb
В некоторых средах разработки первая строка в этом сообщении может быть нажата, чтобы показать местоположение броска в отладчике, поэтому легко установить точку останова и запустить снова, чтобы увидеть неожиданный броск в контексте его стека вызовов.
Why doesn't boost::exception derive from std::exception?
Несмотря на то, чтовиртуальное наследование должно использоваться при выводе из базовых типов исключений, довольно часто типы исключений (включая те, которые определены в стандартной библиотеке) не происходят из std::
Если увеличение::исключениепроисходит от std:: исключение, используявключение_error_infoфункция с такими определяемыми пользователем типами вводила бы опасную двусмысленность, которая ломала бы все уловки (std:: Exception &).
Конечно, бустер::исключениене следует использовать для замены std:: исключение в качестве базового типа в иерархиях типа исключения. Вместо этого он должен быть включен в качестве виртуальной базы, в дополнение к std:: Исключение (которое, вероятно, также должно быть получено виртуально).
Why is boost::exception abstract?
Предотвратить ошибочное стирание типа исходного исключения в исключительных случаях при добавленииerror_infoк активному объекту исключения:
catch( boost::exception & e )
{
e << foo_info(foo);
throw e; //Compile error: boost::exception is abstract
}
Правильный код:
catch( boost::exception & e )
{
e << foo_info(foo);
throw; //Okay, re-throwing the original exception object.
}
Why use operator<< overload for adding info to exceptions?
Перед бросанием объекта типа, происходящего от бустера::исключение, часто желательно добавить в него один или несколькоerror_infoобъектов. Синтаксический сахар, обеспечиваемый оператором, позволяет делать это непосредственно в виде броска:
throw error() << foo_info(foo) << bar_info(bar);
Why is operator<< allowed to throw?
Этот вопрос касается следующего вопроса. Рассмотрим этот пример заявления о броске:
throw file_open_error() << file_name(fn);
Намерение здесь состоит в том, чтобы бросить файл_open_error, однако, еслиоператор<<не сможет скопировать std::string, содержащуюся в обёртке file_nameerror_info, вместо этого может распространяться std::bad_alloc. Такое поведение кажется нежелательным для некоторых программистов.
Bjarne Stroustrup, The C++ Programming Language, 3rd Edition, page 371:
"Бросание исключения требует бросания предмета. Реализация C++ требует наличия достаточного количества резервной памяти, чтобы иметь возможность выбрасывать bad_alloc в случае истощения памяти. Однако не исключено, что выбрасывание какого-то другого исключения вызовет истощение памяти».
Поэтому сам язык не гарантирует, что попытка бросить исключение гарантированно бросает объект указанного типа; распространение std::bad_alloc представляется возможностью даже за пределами области Boost Exception.