2010-11-05 23 views
5

Ci sarebbe qualche differenza Se faccio quanto segue senza usare le eccezioni?Quando rilevare le eccezioni?

void func() 
{ 
    try 
    { 
     if (n > 5) 
     { 
      throw "n is greater than 5"; 
     } 
    } 
    catch (const char *e) 
    { 
     MessageBox(0, e, 0, 0); 
     return; 
    } 
} 

O

void func() 
{ 
    if (n > 5) 
    { 
     MessageBox(0, "n is greater than 5", "Error", 0); 
     return; 
    } 
} 
+1

verrebbe trashed per il lancio di un 'char const *' nel primo caso. –

+0

Potrebbe essere la differenza nel titolo "Errore" e nel reverse engineering del codice. . . – k06a

risposta

8

Direi probabilmente che si consiglia di non utilizzare eccezioni per il controllo del flusso. Le eccezioni, come suggerisce il nome, sono per la gestione di circostanze eccezionali. Nel caso sopra ci si aspetta chiaramente che n sia possibilmente> 5 quindi non è davvero una circostanza eccezionale. Se c'è un modo per la tua applicazione di trattare con quel caso, allora dovrebbe farlo preferibilmente sollevando un'eccezione.

Sono sicuro che ci sono casi in cui questa logica cade, ma in generale penso che sia una buona regola.

Ma in termini tecnici non c'è molta differenza (forse prestazioni se si sta facendo molto).

0

Non c'è vera differenza nel tuo esempio (a parte il fatto ovvio che uno usa le eccezioni e l'altro no!) - che sarebbe un refactoring ragionevole. Tuttavia, se ci sono molte diverse condizioni di errore, è possibile che il modello throw... catch aiuti a mantenere la gestione degli errori in un unico punto.

2

Il risultato finale sarebbe la stessa identica cosa, questo è certo.

Si dovrebbe cercare di semplificare il più possibile le cose nel codice, quindi in questo caso sconsiglio vivamente l'utilizzo di un'eccezione.

0

Nel tuo esempio, non c'è differenza. L'unica cosa che devi capire è che quando viene lanciata un'eccezione, il resto delle affermazioni viene trovato all'interno del metodo try ... catch non verrà mai eseguito. Exceptions sono fondamentalmente usati per gestire "condizioni speciali che cambiano il normale flusso di esecuzione del programma". (il tuo è semplicemente un normale flusso di errori logici).

Spero che questo aiuti.

0
void func() 
{ 
    if (n > 5) 
    { 
     MessageBox(0, "n is greater than 5", "Error", 0); 
     return; 
    } 
} 

Non lanciare l'eccezione da soli, se riesci a gestirlo da solo con un controllo come il codice precedente, Non è una buona pratica.

2

È molto difficile dire esattamente quando devono essere utilizzate le eccezioni. In alcuni casi le eccezioni sono il chiaro vincitore, e in altri casi non lo sono.

Il nocciolo della domanda è da dove proviene n e può essere, in circostanze normali, un valore> 5. Se n è calcolato dalla funzione stessa e può normalmente avere questo valore, allora un'eccezione non sentirsi a posto. Se n tuttavia è specificato altrove, e questa funzione non si aspetta un valore elevato, allora un'eccezione sembra più corretta.

Tuttavia, il tuo esempio direi è un cattivo uso delle eccezioni. Lanciare e catturare un'eccezione all'interno della stessa funzione è quasi sempre una cattiva forma. Questo è il controllo del flusso standard. Le eccezioni dovrebbero essere utilizzate quando una condizione di errore deve propagarsi al di fuori della funzione.

3

Non generare mai un'eccezione che si cattura nella stessa funzione. Questo è un segno che stai usando le eccezioni per il flusso di controllo standard, che è meglio fare con if/while/break/etc.

+1

Mai dire mai! :-) –

+0

@ Alf: di solito non dovresti mai dire mai. Questa è l'unica eccezione! :) –

+0

OK, quindi, un'eccezione all'eccezione alla regola relativa al lancio e alla cattura dell'eccezione nella stessa funzione basata su eccezioni, è quando si emula Java-exception-like 'finally' in C++. Anche se in generale RAII sarà più pulito, suppongo che possa esserci qualche eccezione? Saluti, –

0

Non è stato definito n.

Con la seguente definizione di n v'è diverso comportamento osservabile.

struct Silly 
{ 
    ~Silly() { cout << "Hm de dum" << endl; } 
    operator bool() const { return true; } 
}; 

struct SillyProducer 
{ 
    Silly operator>(int) const { return Silly(); } 
}; 

#define n Silly silly = SillyProducer() 

Acclamazioni & hth,

0

molto è stato già detto, mi limiterò a aggiungere qualcosa dal mio lato.

Nel tuo caso, entrambi i casi sono corretti, tranne che vorrei incoraggiare a suddividere questo in due livelli: la logica e la vista. Così il vostro livello di logica avrebbe fatto:

doLogic() 
    { 
     if (n > 5) 
     { 
     throw "n is greater than 5"; 
     } 
     ///Something more 
    } 

e il vostro livello di visualizzazione potrebbe fare:

try 
{ 
    doLogic() 
} 
catch (const char *e) 
{ 
    MessageBox(0, e, 0, 0); 
    return; 
} 

Ma ancora una volta, come altro ha detto: la cosa più importante è da dove viene il n provenienza. Se ti aspetti che sia superiore a 5, usa solo if() else, non le eccezioni. Ma se n è sempre meno di 5 e se è più di 5 significa che c'è qualcosa che non va nel tuo sistema, quindi usa le eccezioni.

Problemi correlati