Domanda

Il C ++ standard, paragrafo 15.1.4 sais:

  

La memoria per la copia temporanea del all'eccezione generata viene allocata in modo specificato, eccetto come indicato in 3.7.3.1. Il temporanea persiste fino a quando v'è un gestore in corso di esecuzione per tale eccezione.

Mi chiedo il motivo per cui questo codice si blocca (so che non è delle migliori pratiche):

class magicException
{
private:
    char* m_message;

public:
    magicException(const char* message)
    {
        m_message = new char[strlen(message) + 1];
        strcpy(m_message, message);
    }

    ~magicException()
    {
        cout << "Destructor called." << endl;
        delete[] m_message;
    }

    char* getMessage()
    {
        return m_message;
    }
};

void someFunction()
{
    throw magicException("Bang!");
}

int main(int argc, char * argv[])
{
    try
    {
        someFunction();
    }
    catch (magicException& ex)
    {
        cout << ex.getMessage() << endl;
    }

    return 0;
}

In particolare, il distruttore dell'oggetto magicException gettato viene chiamato prima del blocco catch. Se io invece aggiungo un costruttore di copia per la mia classe:

magicException(const magicException& other)
{
    cout << "Copy constructor called." << endl;
    m_message = new char[strlen(other.m_message) + 1];
    strcpy(m_message, other.m_message);
}

Poi il codice funziona, il distruttore viene chiamato nel luogo previsto (fine del blocco catch), ma è interessante notare il costruttore di copia ancora non viene chiamato. E 'ottimizzato via dal compilatore (Visual C ++ 2008 con ottimizzazioni spento), o mi sto perdendo qualcosa?

È stato utile?

Soluzione

  

In particolare, il distruttore della   oggetto magicException gettato ottiene   chiamato prima del blocco catch.

Sì, come il tuo preventivo dallo standard dice, una copia è preso dal compilatore, e l'originale (probabilmente) scartata. Il tuo problema è la mancanza di un costruttore di copia nel codice originale. Tuttavia, un compilatore C ++ è permesso di rimuovere (o aggiungere) copiare le chiamate costruttore in tutti i tipi di situazioni, compreso questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top