перехват объектов-исключений по ссылке, временным объектам, проблемам со сроком службы

StackOverflow https://stackoverflow.com/questions/1860064

  •  13-09-2019
  •  | 
  •  

Вопрос

Рассмотрим следующий код:

#include <iostream>
#include <stdexcept>

void foo()
{
    throw std::runtime_error("How long do I live?");
}

int main()
{
    try
    {
        foo();
    }
    catch (std::runtime_error& e)
    {
        std::cout << e.what() << std::endl;
    }
}

Почему я могу перехватить исключение по ссылке, не так ли std::runtime_error("How long do I live?") значение r?

Как получилось, что объект exception все еще активен в блоке catch?

Где именно хранятся выброшенные объекты исключений?Какова их продолжительность жизни?

Нет правильного решения

Другие советы

В стандарте C ++ пункт 15.1.4:

Память для временной копии генерируемого исключения выделяется неуказанным способом, за исключением случаев, указанных в пункте 3.7.3.1. Временное сохраняется до тех пор, пока существует обработчик, выполняемый для этого исключения.В частности, если обработчик завершает работу, выполнив бросок;оператор, который передает управление другому обработчику для того же исключения, поэтому временное сохраняется.При выполнении последнего обработчика для исключения завершается любым способом кроме throw;временный объект уничтожен, и реализация может освободить память для временного объекта;любое такое освобождение выполняется неуказанным способом.Уничтожение происходит сразу после уничтожения объекта, объявленного в объявлении исключения в обработчике.

Обратите внимание, что в стандартном разговоре на C ++ обработчик обозначает catch блок с правильным типом аргумента.

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

[редактировать] Я просто проверяю стандарт, и он фактически ссылается на временную копию.Однако гарантируется, что время жизни временного объекта будет по крайней мере таким же длительным, как и у обработчика исключений.

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

Спасибо за попытку понять детали языка.При этом, ИМХО, гораздо важнее понять, почему вы должен поймать исключение по ссылке (и выдать его по значению), чем почему вы может.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top