Operátorok:

A C-hez hasonlóan a vezérlési szerkezeteken kívül minden kifejezés. A használható operátorok precedencia sorrendben:

Szint Operátor Arg. Poz. Funkció Felüldefiniálás
17J :: unáris prefix globális scope tilos
17B :: bináris infix osztály scope tilos
16B ->
.
bináris infix tagszelektorok type* class::operator->( void )
tilos
16B [] bináris fgv tömbindex type class::operator[]( indextype )
16B () változó fgv funkcióhívás type class::operator()( arglist )
15J sizeof unáris fgv a kifejezés mérete byte-ban tilos
15J ++
--
unáris prefix preinkrementálás
predekrementálás
type class::operator++( void )
type class::operator--(void)
15J ++
--
unáris postfix postinkrementálás
postdekrementálás
type class::operator++( int )
type class::operator--( int )
15J ~ unáris prefix bitenkénti NEM type class::operator~( void )
15J ! unáris prefix logikai NEM type class::operator!( void )
15J +
-
unáris prefix elojel type class::operator-( void )
type class::operator+( void )
15J *
&
unáris prefix dereferencia, címképzés type class::operator*( void )
type* class::operator&( void )
15J () bináris fgv típuskonverzió (cast) class::operator type( void )
megj: hasonlóan a konstruktorokhoz, a konverziós operátoroknak sincs explicit módon meghatározott visszatérési értékük. A konverziós operátorok visszatérési értéke megeggyezik a céltípussal.
15J new
delete
delete []
unáris prefix tárfoglalás
felszabadítás
tömbök felszabadítása
void* class::operator new( size_t, opc. arglist )
class::operator delete( void * )
14B ->*
.*
bináris infix dereferált tagmutató
tagmutató
type::* class::operator->*( void )
tilos
13B *
/
%
bináris infix szorzás
(egész)osztás
maradékképzés
type1 class::operator*( type2 )
type1 class::operator/( type2 )
type1 class::operator%( type2 )
12B +
-
bináris infix összeadás
kivonás
type1 class::operator+( type2 )
type1 class::operator-( type2 )
11B <<
>>
bináris infix bináris eltolás balra
bináris eltolás jobbra
type1 class::operator<<( type2 )
type1 class::operator>>( type2 )
10B <,<=,><
<=
>
>=
bináris infix relációs operátorok type1 class::operator<( type2 )
type1 class::operator<=( type2 )
type1 class::operator>( type2 )
type1 class::operator>=( type2 )
9B ==
!=
bináris infix egyenlôség, nem egyenlôség type1 class::operator==( type2 )
type1 class::operator!=( type2 )
8B & bináris infix bitenkénti ÉS type1 class::operator&( type2 )
7B ~ bináris infix bitenkénti KIZÁRÓ VAGY type1 class::operator~( type2 )
6B | bináris infix bitenkénti VAGY type1 class::operator|( type2 )
5B && bináris infix logikai ÉS type1 class::operator&&( type2 )
4B || bináris infix logikai VAGY type1 class::operator||( type2 )
3B ? : 3 arg. feltételes kifejezés tilos
2J =
*=
/=
%=
+=
-=
<<=
>>=
&=
&&=
|=
||=
^=
bináris infix értékadás type1 class::operator=( type2 )
type1 class::operator*=( type2 )
type1 class::operator/=( type2 )
type1 class::operator%=( type2 )
type1 class::operator+=( type2 )
type1 class::operator-=( type2 )
type1 class::operator<<=( type2 )
type1 class::operator>>=( type2 )
type1 class::operator&=( type2 )
type1 class::operator&&=( type2 )
type1 class::operator|=( type2 )
type1 class::operator||=( type2 )
type1 class::operator^=( type2 )
1B , bináris infix vesszô operátor type1 class::operator,( type2 )

Az szint a precedencia szintjét jelöli, minél magasabb annál nagyobb a precedencia. A J vagy B karakter a jobbról balra, illetve balról jobbra való asszociativitást jelzi.

Operátorok felüldefiniálása

A C++ nyelv egyik legfobb újítása az operator redefining, vagyis az operátor felüldefiniálás. Ezzel a legtöbb C++ standard operátornak jelentést adhatunk saját osztályaink esetében is. Felüldefiniálni kizárólag olyan operátort lehet, amelyiknek legalább egyik argumentuma nem standard C++ típus.

Egy operátort úgy definiálhatunk felül, hogy definiáljuk a fenti táblázatban található függvényt az osztály tagfüggvényeként. A legtöbb operátort akár virtuális tagfüggénnyel is felüldefiniálhatunk. Unáris operátorok esetében az argumentum a this, bináris operátorok esetében a baloldali argumentum a this lesz, a jobboldali argumentumot pedig az operátorfüggvényben explicit módon definiáljuk.

Néhány operátort osztályszintu, vagy akár külso függvényekkel is felüldefiniálhatunk. Ebben az esetben az unáris operátorok egy explicit módon deklarált argumentummal, míg a bináris operátorok két explicit módon deklarált argumentummal rendelkeznek. Csak ilyen felüldefiniálással oldható meg például egy olyan bináris operátor definiálása, amely baloldali operandusa beépített típus.

Alapveto felüldefiniálási szabályok

Noha az egyes operátorok jelentését tökéletesen megváltoztathatjuk, az adott operátorok asszociativitása és precedenciaszintje nem változik. Ezért nem célszeru az egyes operátorok jelentését a természetestol eltéro módon megváltoztatni.

Rendkívüli figyelemmel végezzük a logikai operátorok felüldefiniálását, ugyanis könnyen nem várt viselkedést érhetünk el ezeknél az operátoroknál, mivel a C++ a logikai operátorok kiértékelésénel az ún. short-circuit algoritmust használja. Ennek lényege, hogy az egyes kifejezéseket csak addig értékeli ki, amíg annak értéke egyértelmuen el nem dol. Tekintve hogy ez a viselkedési mód része a szabványnak, a programozók többsége ezt ki is használja, meghozzá oly módon, hogy programjuk hibátlan muködése ennek a viselkedésnek függvénye. Tekintsük az alábbi példát:

if( (pointer!=null) && (*pointer-=5) ) ...

Amennyiben a fenti kifejezés nem short-circuit módon értékelodne ki, úgy NULL értéku pointernél a program elszállna. Short-circuit kiértékelésnél ezzel szemben a program minden pointerértékre biztonságos.

Amikor azonban felüldefiniálunk egy logikai operátort, a fordító (természetesen) nem feltételezheti, hogy a mi operátorunkat is elegendo short-circuit módon kiértékelni, tehát a függvényhívás kiértékelési módot választja, vagyis mindenképpen kiértékeli mindkét operandust.

A new és a delete operátorok

A new és a delete operátorok felüldefiniálása erosen különbözik a többi operátorétól. Amennyiben a new operátort statikus tagfüggvénnyel definiáljuk, akkor az adott osztály allokálása a felüldefiniált operátor segítségével történik. Amennyiben pedig a new operátort nem tagfüggvényként definiáljuk, úgy egy ún. default new operátort definiálunk, amely segítségével az összes olyan osztály (es beépített típus) allokálása történik, amelyeknek nem lett felüldefiniálva a new operátora.

Alapesetben a new operátor egy size_t típusú argumentumot vesz át, ami meghatározza az allokálandó tárterület mennyiségét. Opcionálisan további argumentumokat is meghatározhatunk, amely esetben a new operátor hívási szintakszisa:

type *p = new( <opt.args> ) type;

A dereferált tagszelektor operátor

A dereferált tagszelektor operátort (->) gyakran használjuk ún. smart pointer osztályok írására. Ezeknek az operátorok, noha igazából bináris operátornak számítanak, csak egy argumentumot vesznek át (a this mutatót). Visszatérési értékük egy olyan struktúrára mutató pointer, amelyet dereferálva, es arra a tagszelekciós operátort alkalmazva elérheto a jobboldali operandusként megadott mezo.