Precedenza negli operatori C++

Da cppreference.com.
< cpp


Gli operatori in cima alla lista sono valutati per primi. Gli operatori all'interno del gruppo hanno la stessa precedenza. Tutti gli operatori hanno asscociazione da sinistra a destra se non scritto diversamente.

\\


Precedenza Operatore Descrizione Esempio Sovrascrivibile Associazione
1 :: Operatore di scope resolution Class::age = 2; no da sinistra a destra
2 () Chiamata di una funzione printf("Hello world\n"); SI da sinistra a destra
::: () Inizializzazione di un membro c_tor(int x, int y) : _x(x), _y(y * 10) {} SI :::
::: [] Accesso ad un array array[4] = 2; SI :::
::: %%->%% Accesso ad un membro da un puntatore %%ptr->age = 34;%% SI :::
::: . Accesso ad un membro da un oggetto obj.age = 34; no :::
::: ++ Post-incremento %%for (int i = 0; i < 10; i++) cout << i;%% SI :::
::: %%--%% Post-decremento %%for (int i = 10; i > 0; i--) cout << i;%% SI :::
::: dynamic_cast Conversione di tipo runtime-checked Y& y = dynamic_cast<Y&>(x); no :::
::: static_cast Conversione di tipo unchecked Y& y = static_cast<Y&>(x); no :::
::: reinterpret_cast Conversione di tipo reinterpretata int const* p = reinterpret_cast<int const*>(0x1234); no :::
::: const_cast Cast away/Add constness int* q = const_cast<int*>(p); no :::
::: typeid Recuperare tipo variabile std::type_info const& t = typeid(x); no :::
3 ! Negazione logica if (!done) %%...%% SI da destra a sinistra
::: not Forma alternativa per ! ::: ::: :::
::: ~ Complemento bit a bit flags = ~flags; SI ::: $
::: compl Forma alternativa per ~ ::: ::: :::
::: ++ Pre-incremento %%for (i = 0; i < 10; ++i) cout << i;%% SI :::
::: %%--%% Pre-decremento %%for (i = 10; i > 0; --i) cout << i;%% SI :::
::: - Riduzione di 1 int i = -1; SI :::
::: + Aggiunta di 1 int i = +1; SI :::
::: * Dereferenziazione int data = *intPtr; SI :::
::: & Indirizzo di... int *intPtr = &data; SI :::
::: sizeof Size del tipo dell'operando in bytes size_t s = sizeof(int); no :::
::: new Allocazione dinamica della memoria long* pVar = new long; SI :::
::: new [] Allocazione dinamica della memoria di un array long* array = new long[20]; SI :::
::: delete Deallocazione della memoria delete pVar; SI :::
::: delete [] Deallocazione della memoria di un array delete [] array; SI :::
::: (type) Cast verso un tipo specifico int i = (int)floatNum; SI :::
4 %%->*%% Selettore di un puntatore %%ptr->*var = 24;%% SI da sinistra a destra
::: .* Selettore di un oggetto obj.*var = 24; no :::
5 * Moltiplicazione int i = 2 * 4; SI da sinistra a destra
::: / Divisione float f = 10.0 / 3.0; SI :::
::: % Modulo int rem = 4 % 3; SI :::
6 + Addizione int i = 2 + 3; SI da sinistra a destra
::: - Sottrazione int i = 5 - 1; SI :::
7 %%<<%% Shift di bit a sinistra %%int flags = 33 << 1;%% SI da sinistra a destra
::: %%>>%% Shift di bit a destra %%int flags = 33 >> 1;%% SI :::
8 < Comparazione less-than if (i < 42) %%...%% SI da sinistra a destra
::: %%<=%% Comparazione less-than-or-equal-to %%if (i <= 42) ...%% SI :::
::: > Comparazione greater-than if (i > 42) %%...%% SI :::
::: %%>=%% Comparazione greater-than-or-equal-to %%if (i >= 42) ...%% SI :::
9 %%==%% Comparazione equal-to %%if (i == 42) ...%% SI da sinistra a destra
::: eq Forma alternativa per %%==%% ::: ::: :::
::: != Comparazione not-equal-to if (i != 42) %%...%% SI :::
::: not_eq Forma alternativa per != ::: ::: :::
10 & AND di bit flags = flags & 42; SI da sinistra a destra
::: bitand Forma alternativa per & ::: ::: :::
11 %% %% OR esclusivo di bit (XOR) %%flags = flags 42;%% SI da sinistra a destra
::: xor Forma alternativa per %% %% ::: ::: :::
12 %% %% OR inclusivo di bit %%flags = flags 42;%% SI da sinistra a destra
::: bitor Forma alternativa per %% %% ::: ::: :::
13 && AND logico if (conditionA && conditionB) %%...%% SI da sinistra a destra
::: and Forma alternativa per && ::: ::: :::
14 %% %% OR logico %%if (conditionA conditionB) ...%% SI da sinistra a destra
::: or Forma alternativa per %% %% ::: ::: :::
15 ? : Condizionale ternario (if-then-else) int i = a > b ? a : b; no da destra a sinistra
16 = Operatore di assegnamento int a = b; SI da destra a sinistra
::: += Incremento e assegnazione a += 3; SI :::
::: -= Decremento e assegnazione b -= 4; SI :::
::: *= Moltiplicazione e assegnazione a *= 5; SI :::
::: /= Divisione e assegnazione a /= 2; SI :::
::: %= Modulo e assegnazione a %= 3; SI :::
::: &= AND di bit e assegnazione flags &= new_flags; SI :::
::: and_eq Forma alternativa per &= ::: ::: :::
::: %% =%% XOR di bit e assegnazione %%flags = new_flags;%% SI :::
::: xor_eq Forma alternativa per %% =%% ::: ::: :::
::: %% =%% OR di bit e assegnazione %%flags = new_flags;%% SI :::
::: or_eq Forma alternativa per %% =%% ::: ::: :::
::: %%<<=%% Shift di bit a sinistra e assegnazione %%flags <<= 2;%% SI :::
::: %%>>=%% Shift di bit a destra e assegnazione %%flags >>= 2;%% SI :::
17 throw throw exception throw EClass("Message"); no
18 , Operatore di valutazione sequenziale for (i = 0, j = 0; i < 10; i++, j++) %%...%% SI da sinistra a destra

[modifica] Ordine di valutazione e side effect

Un aspetto importante del C++ in relazione alla precedenza degli operatori è l'ordine di valutazione e l'ordine dei side effect nelle espressioni. In molte circostanze l'ordine di come avvengono le cose non è specificato. Per esempio in f() + g() ,quale fra f() o g() è chiamato prima non è specificato. Se almeno una funzione ha side effect, il risultato può differire in funzione del compilatorem,delle differenti versioni dello stesso compilatore o fra diversi accessi allo stesso compilatore.

In più l'effetto di certe espressioni non è definita. Per esempio, considerando il codice seguente:

    float x = 1;
    x = x / ++x;

Il valore di x e il resto del comportamento del programma dopo la valutazione dell'espressione non è definito. Il programma è semanticamente ill-formed: x è modificato doppiamente fra due punti consecutivi.

Espressioni come quella scritta sopra devono essere evitate. Quando c'è un dubbio, rompere l'espressione più grande in sotto-espressioni per assicurare che la valutazione sia corretta.

[modifica] Overloading degli operatori

L'overloading degli operatori può essere molto utile e molto pericoloso. Da una parte l'overload delgi operatori per una classe creata può aiutare il trasporto e la leggibilità del codice. Dall'altra parte si potrebbe sovraccaricare un operatore in modo da rendere offuscato o rovinare il proprio programma.Fai Attenzione! In particolare mai eseguire l'overload di &&, || o ,. Nel contesto overloaded si perde la garanzia che loperando sinistro sia valutato prima del secondo e che ci sia una sequenza di punti fra di loro.

Ci sono due modi per sovraccaricare un operatore: global function o class member.

Esempio di overloading con una global function:

     ostream& operator <<(ostream& os, const myClass& rhs);

Ma per raggiungere qualsiasi dato private all'interno della classe definita dall'utente, si deve dichiarare la global function come friend all'interno della definizione della classe.

Esempio:

     class myClass {
 
       // Gives the operator << function access to 'myData'
       // (this declaration should not go in public, private or protected)
       friend ostream& operator <<(ostream& lhs, const myClass& rhs);
 
       private:
         int myData;
     }

L'overloading con una classe può essere eseguito come segue:

     class myClass {
 
       public:
         // The left hand side of this operator becomes '*this'.
         int operator +(const myClass& rhs);
 
       private:
         int myData;
     }
Strumenti personali
Namespace
Varianti
Azioni
Navigazione
Strumenti
Altre lingue