captura exceção objetos por referência, temporários, questões de vida

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

  •  13-09-2019
  •  | 
  •  

Pergunta

Considere o seguinte código:

#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;
    }
}

Por que eu posso capturar a exceção por referência, não é std::runtime_error("How long do I live?") um rvalue?

Como é que o objeto de exceção ainda está vivo no bloco catch?

objetos de exceção Onde exatamente são jogados armazenados? Qual é a sua vida?

Nenhuma solução correta

Outras dicas

No padrão C ++, parágrafo 15.1.4:

A memória para a cópia temporária os está sendo exceção lançada concedido de uma forma não especificada, com a excepção indicada em 3.7.3.1. A persiste temporários como desde que haja um manipulador que está sendo executado para que exceção . Em particular, se um manipulador de saídas por executando um tiro; declaração, que passa o controle para outro manipulador para o mesmo excepção, de modo que os restos temporárias. Quando o último manipulador ser executado para as saídas de exceção por qualquer meio diferente do lance; o objecto temporário é destruído ea implementação pode desalocar a memória para o objeto temporário; Qualquer tal deallocation é feito em um não especificado caminho. A destruição ocorre imediatamente após a destruição de o objeto declarado no exception-declaração no manipulador.

Note-se que, em C ++ -. Conversa standard, um manipulador denotam um bloco catch com o tipo de argumento correto

A exceção lançada não é um temporário - o código de exceção gerado pelo compilador mantém uma cópia permanente do mesmo. Assim, você pode vinculá-lo a uma referência não-const.

[editar] Eu só verificar o padrão e ele realmente se refere a uma cópia temporária. No entanto, a vida útil do temporário é garantida para ser pelo menos tão longo como o do manipulador de exceção.

Como Neil disse, não há mágica interno do compilador acontecendo. Além disso, estar ciente de que o compilador é permitido para criar qualquer número de cópias do objeto de exceção.

Kudos para tentar entender os detalhes da linguagem. Ao mesmo tempo, IMHO, é muito mais importante para entender por que você deve capturar uma exceção por referência (e jogá-lo por valor), do que por que você pode .

As pessoas normalmente usam uma hierarquia de classes de exceção, e captura por referência permite polimorfismo alavancagem, e capturar uma exceção da classe base, quando não há necessidade de lidar com tipos de exceção individuais separadamente. Se você não poderia pegar por referência, você teria que escrever uma cláusula catch para cada tipo possível de exceção que pode ser jogado na cláusula try.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top