2010-06-28 14 views
17

Wikipedia dice che "Un pezzo di codice è detto sicuro per le eccezioni, se i guasti di runtime all'interno del codice non producono effetti negativi, come perdite di memoria, dati memorizzati confusi o output non valido. Il codice eccezionalmente sicuro deve soddisfare gli invarianti inseriti nel codice anche se si verificano eccezioni. "Eccezione sicurezza in Qt

E sembra che abbiamo bisogno di gestione delle eccezioni per la sicurezza delle eccezioni. D'altra parte, la gestione delle eccezioni non è molto popolare nelle applicazioni Qt finché riesco a vedere.

Quali sono le migliori pratiche in Qt per soddisfare la sicurezza delle eccezioni? Cosa usi invece della gestione delle eccezioni?

+1

QT è una libreria molto vecchia e molto povera quando si tratta di sicurezza eccezionale. Considerare come tutti i widget devono essere allocati all'heap ma non esiste un puntatore intelligente per RAII. Il meglio che puoi fare è assegnarli in un auto_ptr e rilasciare la memoria al genitore/layout quando si inserisce.Hanno alcune disposizioni di base come QMutexLocker dal momento che lanciare mentre un mutex è bloccato sarebbe disastroso, ma c'è molto di più di cui hanno bisogno o molto lavoro da fare per usare qt in un modo sicuro per le eccezioni . – stinky472

+8

@ stinky472: sbagliato. [QSharedPointer] (http://doc.trolltech.com/4.6/qsharedpointer.html) – MSalters

+0

@ stinky472: quali toolkit della GUI consentono ai widget di essere allocati allo stack? E perché vorresti farlo? Sembra un argomento "uomo di paglia". – kevinarpe

risposta

10

C++ ha un meccanismo molto potente per excpetion-sicurezza. I distruttori vengono eseguiti per tutte le variabili che escono dall'ambito a causa di un'eccezione. Ciò differisce dalle lingue come Java, dove la sicurezza delle eccezioni richiede al programmatore di ottenere le clausole catch e finally.

Il comportamento C++ di chiamare i distruttori funziona perfettamente con gli oggetti Qt nello stack. Le classi Qt hanno tutti i distruttori e nessuno richiede la pulizia manuale. Inoltre, è possibile utilizzare QSharedPointer<T> per gestire oggetti Qt allocati su heap; quando l'ultimo puntatore esce dall'ambito, l'oggetto viene distrutto. Ciò include il caso in cui il puntatore esce dall'ambito a causa di un'eccezione.

Quindi, la sicurezza delle eccezioni è certamente presente in Qt. È solo trasparente.

+2

Penso che il problema con QSharedPointer sia che non è usato in molti posti. Ad esempio, un QLayout si aspetta QWidget * con l'aspettativa che QLayout diventi il ​​gestore di memoria per esso. Non possiamo usare QSharedPointer qui perché QLayout dovrebbe eliminare il widget quando viene rimosso dal layout. :-( – stinky472

+3

Il post originale dell'autore ha dichiarato che "la gestione delle eccezioni non è molto popolare nelle applicazioni Qt finché vedo" che è esattamente vero. L'esistenza di QSharedPointer non modifica nulla perché alcune parti dell'API QT e dei suoi esempi lo utilizzano effettivamente Invece abbiamo esempi come QButton * button = new QButton (...); QVBoxLayout * layout = new QVBoxLayout (...); la libreria è, per la maggior parte, non codificata per essere protetta da eccezioni. dovrebbe essere affrontato e fare in modo che più parti della libreria accettino e memorizzino QSharedPointer sarebbe un'ottima soluzione. – stinky472

2

La mia pratica migliore è quella di non utilizzare (o almeno evitarli il più possibile) eccezioni C++ nel codice basato su Qt, il che rende la loro gestione un problema. Tuttavia, non è questa la vera ragione, mi sento semplicemente che le eccezioni spesso rendono le cose inutilmente più complicate di quanto dovrebbero essere. Ma aiuta Qt si è per lo più problemi di eccezione libero ... :)

7

Qt è (per lo più) non è sicuro eccezione: http://doc.qt.io/archives/4.6/exceptionsafety.html

D'altra parte si tratta di eccezioni correttamente in event driven di programmazione è molto difficile , quindi meglio è quello di evitarli quando si utilizza Qt e passare i codici di errore.

+10

Perché gestire correttamente le eccezioni nella programmazione guidata dagli eventi è molto difficile? – metdos

1

Le classi Qt sono exception neutral come indicato nello documentation.

È necessario attenersi ai valori booleani per gestire le condizioni di errore, proprio come Qt stesso.

Non utilizzare eccezioni internamente è stato fatto per motivi di trasferibilità, perché Qt deve supportare molte piattaforme diverse (la portabilità e le eccezioni non si combinano bene).

Nuovamente, dalla documentazione:

Attualmente, il caso d'uso supportato solo per il recupero da eccezioni generate all'interno Qt (ad esempio a causa di memoria) è uscire dal ciclo di eventi e fare qualche pulizia prima uscire dall'applicazione. tipico caso d'uso:

QApplication app(argc, argv); 
... 
try { 
    app.exec(); 
} catch (const std::bad_alloc &) { 
    // clean up here, e.g. save the session 
    // and close all config files. 

    return 0; // exit the application 
} 
+4

Si noti che Qt ha una cronologia che risale al momento in cui le eccezioni erano nuove. La portabilità nel XXI secolo è molto più semplice. – MSalters

+0

Hai ragione, avrei dovuto sottolinearlo. Anche se non so molto sulle eccezioni e Symbian, specialmente con le versioni più recenti. So che le versioni precedenti utilizzavano un meccanismo di gestione delle eccezioni sostanzialmente differente. –

+0

Symbian è un dolore; nessuna sorpresa date le sue radici EPOC degli anni '80. Ma Qt e Symbian non sono correlati a questo. Symbian ha avuto origine da Psion; Qt at TrollTech. – MSalters