Traductions de cette page?:

Précédence des opérateurs C++

Les opérateurs en haut de la liste sont évalués en premiers. Les opérateurs à l'intérieur d'un même groupe partagent la même précédence. Tout les opérateurs ont une associativité de gauche à droite sauf exception.

Opérateur Description Exemple Surchargeable
Groupe 1
(pas d'associativité)
::Opérateur de résolutionClass::age = 2;NON
Groupe 2
()Appel de fonctionisdigit('1')OUI
()Initialisation de membre c_tor(int x, int y) : _x(x), _y(y*10){};OUI
[]Accès à l'élément d'un tableauarray[4] = 2;OUI
->Accès à un membre depuis un pointeurptr->age = 34;OUI
.Accès à un membre depuis un objetobj.age = 34;NON
++Post-incrémentationfor( int i = 0; i < 10; i++ ) cout << i;OUI
--Post-décrémentationfor( int i = 10; i > 0; i-- ) cout << i;OUI
const_castTranstypageconst_cast<type_vers>(type_de);NON
dynamic_castTranstypagedynamic_cast<type_vers>(type_de);NON
static_castTranstypagestatic_cast<type_vers>(type_de);NON
reinterpret_castTranstypagereinterpret_cast<type_vers>(type_de);NON
typeidInformation sur le typecout << typeid(var).name();
cout << typeid(type).name();
NON
Groupe 3
(associativité droite-à-gauche)
!Négation logiqueif( !fini ) …OUI
notAutre notation pour !
~Complément bit à bitdrapeaux = ~drapeaux;OUI
complAutre notation pour ~
++Pré-incrémentationfor( i = 0; i < 10; ++i ) cout << i;OUI
--Pré-décrémentationfor( i = 10; i > 0; --i ) cout << i;OUI
-Moins unaireint i = -1;OUI
+Plus unaireint i = +1;OUI
*Déréferenciationint data = *intPtr;OUI
&Adresse deint *intPtr = &data;OUI
newAllocation dynamique de mémoirelong *pVar = new long;
MyClass *ptr = new MyClass(args);
OUI
new []Allocation dynamique de mémoire pour tableaulong *array = new long[n];OUI
deleteDésallocation de mémoire delete pVar;OUI
delete []Désallocation de mémoire d'un tableau delete [] array;OUI
(type)Transtypage vers un type donnéint i = (int) floatNum;OUI
sizeofTaille d'un objet ou d'un typeint size = sizeof floatNum;
int size = sizeof(float);
NON
Groupe 4
->*Accès à un membre pointé depuis un pointeurptr->*var = 24;OUI
.*Accès à un membre pointéobj.*var = 24;NON
Groupe 5
*Multiplicationint i = 2 * 4;OUI
/Divisionfloat f = 10.0 / 3.0;OUI
%Moduloint rem = 4 % 3;OUI
Groupe 6
+Additionint i = 2 + 3;OUI
-Soustractionint i = 5 - 1;OUI
Groupe 7
<<Décalage binaire à gaucheint drapeaux = 33 << 1;OUI
>>Décalage binaire à droiteint drapeaux = 33 >> 1;OUI
Groupe 8
<Comparaison inférieur àif( i < 42 ) …OUI
<=Comparaison inférieur ou égal àif( i <= 42 ) ...OUI
>Comparaison supérieur àif( i > 42 ) …OUI
>=Comparaison supérieur ou égal àif( i >= 42 ) ...OUI
Groupe 9
==Comparaison égal àif( i == 42 ) ...OUI
eqAutre notation pour ==
!=Comparaison non égal àif( i != 42 ) …OUI
not_eqAutre notation pour !=
Groupe 10
&ET bit à bitdrapeaux = drapeaux & 42;OUI
bitandAutre notation pour &
Groupe 11
^OU exclusif bit à bit (XOR)drapeaux = drapeaux ^ 42;OUI
xorAutre notation pour ^
Groupe 12
|OU inclusif bit à bit (normal)drapeaux = drapeaux | 42;OUI
bitorAutre notation pour |
Groupe 13
&&ET logiqueif( conditionA && conditionB ) …OUI
andAutre notation pour &&
Groupe 14
||OU logiqueif( conditionA || conditionB ) ...OUI
orAutre notation pour ||
Groupe 15
(associativité droite-à-gauche)
? :Condition ternaire (si-alors-sinon)int i = (a > b) ? a : b;NON
Groupe 16
(associativité droite-à-gauche)
=Opérateur d'assignementint a = b;OUI
+=Incrémenter et assignera += 3;OUI
-=Décrémenter et assignerb -= 4;OUI
*=Multiplier et assignera *= 5;OUI
/=Diviser et assignera /= 2;OUI
%=Modulo et assignera %= 3;OUI
&=ET bit à bit et assignerdrapeaux &= nouveaux_drapeaux;OUI
and_eqAutre notation pour &=
^=OU exclusif bit à bit (XOR) et assignerdrapeaux ^= nouveaux_drapeaux;OUI
xor_eqAutre notation pour ^=
|=OU normal bit à bit et assignerdrapeaux |= nouveaux_drapeaux;OUI
or_eqAutre notation pour |=
<<=Décalage binaire à gauche et assignerdrapeaux <<= 2;OUI
>>=Décalage binaire à droite et assignerdrapeaux >>= 2;OUI
Groupe 17
throwLever une exceptionthrow EClass(“Message”);NON
Groupe 18
,Opérateur d'évaluation séquentiellefor( i = 0, j = 0; i < 10; i++, j++ ) …OUI

Ordre d'évaluation et effets de bords

L'un des aspects importants du C++ qui est relié à la précédence des opérateurs est l'ordre d'évaluation et l'ordre des effets de bords dans les expressions. Dans certaines circonstances, l'ordre dans lequel les choses se passent n'est pas défini. Par exemple, étudions le code suivant:

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

Il n'est pas garanti que la valeur de x soit constante selon différent compilateurs, parce qu'il n'est pas clairement spécifié si l'ordinateur doit évaluer le coté gauche ou droit de la division en premier. Selon le coté évalué en premier, x peut prendre une valeur différente.

De plus, alors que ++x est évalué comme x+1, le fait de stocker la nouvelle valeur dans x peut se passer à différents moments, résultant de différentes valeurs pour x.

Enfin, les expressions comme celle-ci sont horriblement ambiguës et doivent à tout prix être évitées. Dans le doute, séparez une expression ambiguë en plusieurs expressions pour assurer que l'ordre d'évaluation est correct.

Surcharge des opérateurs

La surcharges des opérateurs peut être très utile et très dangereuse. D'un coté surcharger les opérateurs d'une classe que vous avez crée peut simplifier le code et améliorer sa lisibilité. D'un autre coté vous pouvez surcharger un opérateur d'une telle façon que cela peut masquer un problème ou simplement boguer votre programme. A utiliser avec précaution.

Il y a deux façon de surcharger un opérateur: par une fonction globale ou un membre de classe.

Exemple de surcharge par une fonction global:

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

Mais pour être capable d'atteindre toutes les données privées définies dans une classe vous devez déclarer la fonction globale comme amie dans la definition de la classe.

Exemple:

     class maClasse {
 
       // Donne à la fonction operator<< accès à 'maDonnee'
       // (cette déclaration ne doit pas être définie comme publique, privée ou protégée)
       friend ostream & operator<< (ostream & lhs, const maClasse & rhs);
 
       private:
         int maDonnee;
     }

La surcharge par un membre de classe peut être faite comme cela:

     class maClasse {
 
       public:
         // Le coté gauche de l'opérateur est un pointeur vers 'this'.
         int operator+ (const maClasse & rhs);
 
       private:
         int maDonnee;
     }