Questa è una lista degli operatori nei linguaggi di programmazione C e C++. Tutti gli operatori seguenti sono implementabili in quest'ultimo linguaggio, mentre invece altri non lo sono in C, come nel caso degli operatori di conversione di tipo (casting), ossia const_cast, static_cast, dynamic_cast, e reinterpret_cast.

Molti degli operatori disponibili in C e C++ sono implementabili pure in altri linguaggi della cosiddetta “famiglia C”, quali C#, D, ma anche Java, Perl e PHP, mantenendo le medesime caratteristiche mostrate (arietà, posizione e associatività).

Sintassi degli operatori Nelle tabelle seguenti, a, b e c rappresentano valori validi qualsiasi (literals, valori da variabili, oppure return value) o, in alcuni casi specifici, nomi di oggetti o lvalues. R, S e T indicano qualsiasi tipo, mentre K indica un tipo di classe o un tipo enum.

Operatori aritmetici Tutti gli operatori aritmetici esistono sia in C e C++ e possono essere, come già indicato, sovraccaricati solo in C++. +Nome operatoreSintassiEsempi di implementazione in C++Come membro della classe KFuori dalla classeAddizionea+bR K::operator +(S b);R operator +(K a, S b);Sottrazionea-bR K::operator -(S b);R operator -(K a, S b);Unario più+aR K::operator +();R operator +(K a);Unario meno -aR K::operator -();R operator -(K a);Moltiplicazionea * bR K::operator *(S b);R operator *(K a, S b);Divisionea / bR K::operator /(S b);R operator /(K a, S b);Moduloa % bR K::operator %(S b);R operator %(K a, S b);IncrementoPrefisso++aR& K::operator ++();R& operator ++(K& a);Postfissoa++R K::operator ++(int);R operator ++(K& a, int);Il C++ utilizza il parametro fittizio senza nome int per differenziare gli operatori di incremento prefisso e postfisso.DecrementoPrefisso--aR& K::operator --();R& operator --(K& a);Postfissoa--R K::operator --(int);R operator --(K& a, int);Il C++ utilizza il parametro fittizio senza nome int per differenziare gli operatori di incremento prefisso e postfisso.

Operatori relazionali Tutti gli operatori di confronto possono essere sovraccaricati solo in C++. Dal C++20, l'operatore di disuguaglianza viene generato automaticamente se viene definito operator== e tutti e quattro gli operatori relazionali vengono generati automaticamente se viene definito operator<=>. +Nome operatoreSintassiIncluso in CEsempi di implementazione in C++Come membro della classe KFuori dalla classeUguale a = bbool K::operator ==(S const& b) const;bool operator ==(K const& a, S const& b);Diversoa != b bool K::operator !=(S const& b) const;bool operator !=(K const& a, S const& b);Maggiore dia > b bool K::operator >(S const& b) const;bool operator >(K const& a, S const& b);Minore dia < b bool K::operator <(S const& b) const;bool operator <(K const& a, S const& b);Maggiore o uguale aa >= b bool K::operator >=(S const& b) const;bool operator >=(K const& a, S const& b);Minore o uguale aa <= b bool K::operator <=(S const& b) const;bool operator <=(K const& a, S const& b);

Operatori logici (o booleani) Tutti gli operatori logici (o booleaniL'accezione booleana è stata coniata in onore del matematico George Boole. ) sono esistenti sia in C che in C++ e possono essere chiaramente sovraccaricati solo in quest'ultimo linguaggio di programmazione.

Nonostante la possibilità di sovraccarico in C++, tale operazione è sconsigliata con AND logico e OR logico sia sconsigliato perché, come operatori sovraccaricati, si comporterebbero come normali chiamate di funzione, il che significa che entrambi i loro operandi verrebbero valutati, perdendo di conseguenza la loro importante valutazione di McCarthy. Nome dell'operatoreSintassi Esempi di implementazione in C++ Come membro della classe K Fuori dalla classeNOT logico ! abool K::operator !();bool operator !(K a);AND logico a && bbool K::operator &&(S b);bool operator &&(K a, S b);OR logico a || bbool K::operator ||(S b);bool operator ||(K a, S b);

Operatori bit a bit Tutti gli operatori bit a bit (o di manipolazione dei bit) esistono sia C che C++ e possono essere sovraccaricati soltanto nel linguaggio inventato da Bjarne Stroustrup. +Nome dell'operatoreSintassiEsempi di implementazione in C++Come membro della classe KFuori dalla classeComplemento a uno (inversione di tutti i bit)~aR K::operator ~();R operator ~(K a);AND bit a bita & bR K::operator &(S b);R operator &(K a, S b);OR inclusivo bit a bita | bR K::operator |(S b);R operator |(K a, S b);OR esclusivo bit a bit (OR exclusive, XOR)a ^ bR K::operator ^(S b);R operator ^(K a, S b);Spostamento di tutti i bit verso sinistraa << bR K::operator <<(S b);R operator <<(K a, S b);Spostamento di tutti i bit verso destraa >> bR K::operator >>(S b);R operator >>(K a, S b);

Operatori ed espressioni di assegnamento Tutti gli operatori e le espressioni di assegnamento sono esistenti sia in C che in C++ e possono essere chiaramente sovraccaricate solo in quest'ultimo linguaggio di programmazione.

Per gli operatori indicati, la semantica dell'espressione di assegnazione combinata incorporata a ⊚= b è equivalente a a = a ⊚ b, eccetto per il fatto che a viene valutata una sola volta. +Tipologia assegnamentoSintassiEsempi di implementazione in C++Come membro della classe KFuori dalla classeEspressione semplice di assegnamentoR& K::operator =(S b);Assegnamenti compostia += bR& K::operator +=(S b);R& operator +=(K& a, S b);a -= bR& K::operator -=(S b);R& operator -=(K& a, S b);a *= bR& K::operator *=(S b);R& operator *=(K& a, S b);a /= bR& K::operator /=(S b);R& operator /=(K& a, S b);a %= bR& K::operator %=(S b);R& operator %=(K& a, S b);a &= bR& K::operator &=(S b);R& operator &=(K& a, S b);a |= bR& K::operator |=(S b);R& operator |=(K& a, S b);a ^= bR& K::operator ^=(S b);R& operator ^=(K& a, S b);a <<= bR& K::operator <<=(S b);R& operator <<=(K& a, S b);a >>= bR& K::operator >>=(S b);R& operator >>=(K& a, S b);

Operatori membro e puntatore +Nome operatoreSintassiAmmette overload (sovraccarico) in C++Implementabile in CEsempi di implementazione in C++Come membro della classe KFuori dalla classeIndicizzazionea[b]R& K::operator [](S b); R& K::operator [](S b, ...); // since C++23Deferenziazione*aR& K::operator *();R& operator *(K a);Indirizzo&aR* K::operator &();R* operator &(K a);Deferenziazione e selezionea->bR* K::operator ->();Selezione (object.member)a.bDeferenziazione e selezione con puntatore a membroa->*bR& K::operator ->*(S b);R& operator ->*(K a, S b);Selezione con puntatore a membroa.*b

Altri operatori +Nome operatoreSintassiAmmette overload (sovraccarico) in C++Implementabile in CEsempi di implementazione in C++Come membro della classe KFuori dalla classeChiamata di funzionea(a1, a2)R K::operator ()(S a, T b, ...);Virgolaa, bR K::operator ,(S b);R operator ,(K a, S b);Espressione condizionalea ? b : cRisolutore di visibilitàa::bDimensione di oggetto o di tipo (sizeof)sizeof a sizeof (R)Conversione di tipo static_caststatic_cast<R>(a)K::operator R(); explicit K::operator R(); since C++11Per le conversioni definite dall'utente, il tipo di ritorno corrisponde implicitamente e necessariamente al nome dell'operatore, a meno che il tipo non sia dedotto. (es. operator auto(), operator decltype(auto)() etc.).Conversione const const_castconst_cast<R>(a)Allocazionenew Rvoid* K::operator new(size_t x);void* operator new(size_t x);Allocazione di arraynew R[n]void* K::operator new[](size_t a);void* operator new[](size_t a);Deallocazionedelete avoid K::operator delete(void* a);void operator delete(void* a);Deallocazione di arraydelete[] avoid K::operator delete[](void* a);void operator delete[](void* a);

Overloading degli operatori C++ possiede molti operatori già predefiniti in grado di operare su vari tipi di dato, perciò si può parlare di “operatori già sovraccaricati”. Per esempio l’operatore + può essere implementato per sommare sia due variabili di tipo int (interi), sia due variabili di tipo float o double (variabili a virgola mobile).

Oltre a quando detto in precedenza, il programmatore può anche “estendere” l’operatività di ciascuno di essi; per esempio operandi complessi definiti con le classi, si potrebbero trattare anche come se fossero dati semplici.

In C++ è possibile sovraccaricare tutti gli operatori predefiniti, con l’eccezione su accesso al membro (.), indirezione di accesso al membro (.*) e risoluzione di ambito (::).

Nel caso degli operatori, il numero degli operandi e la priorità dell’operatore sovraccaricato sono le stesse dell’operatore predefinito, mentre il nuovo operatore può essere definito come una funzione membro oppure come una funzione friend (funzione amica).

Proprietà degli operatori Ogni operatore possiede delle proprietà, in modo tale da permettere l'interpretazione univoca del significato di ogni singola espressione. Gli esempi che seguono sono tutti applicabili al linguaggio C++ e, a seconda dei casi, anche al C.

Posizione Un operatore può precedere gli operandi (o argomenti), seguirli oppure né precederli né seguirli. In questi casi parleremo rispettivamente di operatori prefissi, postfissi oppure infissi.

Numero di operandi Ogni operatore può avere un numero diverso di operandi (arietà). a[b]Nel caso riportato, l'operatore di indicizzazione possiede due operandi, ossia le parentesi quadre. L'arietà può essere anche di tre operandi, come nel caso degli operatori condizionali, riportato di seguito:e1 ? e2 : e3

Precedenza degli operatori Ogni operatore possiede una propria precedenzaThe ISO C 1999 standard, section 6.5.6 note 71 (Technical report). ISO. 1999., rappresentata attraverso un numero naturale tra 1 e 18 in ordine decrescente, dove più è piccolo il numero, maggiore sarà la priorità; per esempio un operatore con priorità 1 avrà maggiore priorità su un operatore con priorità 13.

Nell'esempio che segue è possibile osservare una semplice applicazione pratica delle precedenze: #include <iostream> using namespace std;

int main () { int a = 5; int b = 6; int c = 8;

int op = a+b*c; cout << op << endl; // Stampa a schermo

return 0; }L'operatore moltiplicazione (*) possiede priorità 5, mentre l'operatore addizione (+) possiede priorità 6; pertanto il risultato a schermo sarà 53 e non 19.

Associatività degli operatori L'associatività indica l'ordine in cui vengono eseguiti gli operatori aventi la stessa priorità tra loro. Viene riportato un semplice esempio con gli operatori di divisione (priorità 5). #include <iostream> using namespace std;

int main (){ float a = 5.0; float b = 6.0; float c = 8.0;

float div = a/b/c; cout << div << endl; // Stampa a schermo

return 0; }Nell'esempio precedente la stampa a schermo sarà 0.104167 perché l'operatore di divisione segue associatività a sinistra e, quindi, il calcolatore avrà eseguito la seguente equazione: .

Tabella delle precedenze e delle associatività Nella tabella seguente sono elencati gli operatori di C e C++ in ordine di priorità con le loro rispettive associatività. Essi sono sempre implementabili su C++, mentre, quelli appositamente indicati nella penultima colonna da sinistra, non lo sono in C. +PrioritàOperatoreNomeImplementabile in CAssociatività1 (priorità massima)class-name :: member namespace-name :: memberRisolutore di visibilitàsinistra:: memberRisolutore globale di visibilitàdestra2object . memberSelezionesinistrapointer -> memberDeferenziazione e selezionesinistraarray[ rvalue ]Indicizzazionesinistrafunction ( actual-argument-list )Chiamata di funzionesinistralvalue ++Postincrementodestralvalue --Postdecrementodestrastatic_cast type<rvalue>Conversione di tiposinistraconst_cast type<rvalue>Conversione constsinistra3sizeof object sizeof (type)Dimensione di oggetto