2015-01-02 17 views
7

Uso la seguente classe per impostare automaticamente il cursore in attesa all'inizio di una determinata funzione e ripristinare il cursore quando la funzione ritorna.Il compilatore C++ è autorizzato a ottimizzare gli oggetti locali senza riferimento

class WaitCursorSetter 
{ 
public: 
    WaitCursorSetter() {QApplication::setOverrideCursor(Qt::WaitCursor);} 
    virtual ~WaitCursorSetter() {QApplication::restoreOverrideCursor();} 
}; 

Creazione di un oggetto locale WaitCursorSetter all'avvio della funzione. Poiché il cursore di attesa viene ripristinato nel distruttore dell'oggetto, non devo reimpostare il cursore prima di ogni singola istruzione di ritorno nel metodo, dal momento che il distruttore viene chiamato quando la funzione ritorna e l'oggetto esce dall'ambito.

Se il compilatore ha ottimizzato l'oggetto WaitCursorSetter senza riferimento, questo non funzionerà. Il mio problema è, il compilatore ha permesso di ottimizzare questo oggetto?

risposta

6

Il compilatore non è permesso di ottimizzare la distanza di un oggetto automatico di cui distruttori o initlization ha effetti collaterali, possiamo vedere questo andando al progetto di sezione standard 3.7.3:

Se una variabile con durata di memorizzazione automatica ha inizializzazione o un distruttore con effetti collaterali, non deve essere distrutto prima della fine del blocco, né deve essere eliminato come un'ottimizzazione anche se sembra non essere utilizzato, eccetto che un oggetto di classe o la sua copia/mossa può essere essere eliminato come specificato in 12.8.

0

Se è possibile osservare diversamente, il compilatore non è autorizzato a rimuovere l'oggetto.

In questo caso il costruttore/distruttore ha effetti collaterali, quindi il compilatore non li rimuoverà.

L'idea di delegare effetti alla costruzione/distruzione di oggetti locali basati su stack viene utilizzata spesso; per esempio:

{ 
    Locker L(my_lock); 
    ... 
} 

In questo modo il codice in ... sarà in esecuzione con una serratura che si terrà, e il blocco verrà rilasciato automaticamente quando si lascia il campo per qualsiasi ragione (appena uscire del blocco, l'esecuzione di un return o e se viene lanciata un'eccezione all'interno).

2

È perfettamente sicuro farlo. In effetti, è una tecnica usata spesso quando si mette in pratica RAII. Il compilatore non ottimizzerà alcuna variabile locale che ha non-banale costruttore o distruttore. Controlla What is a non-trivial constructor in C++.

Per evitare anche l'avviso del compilatore relativo alle variabili locali non utilizzate, è possibile utilizzare la macro Q_UNUSED.

Problemi correlati