05 operatory cz2 prez

background image

Przeci ˛

a˙zanie operatorów (odsłona druga)

Bogdan Kreczmer

ZPCiR IIAiR PWr

pokój 307 budynek C3

bogdan.kreczmer@pwr.wroc.pl

Copyright c

°

2005–2009 Bogdan Kreczmer

?

?

Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udost ˛epniony pod

warunkiem wykorzystania wył ˛

acznie do własnych prywatnych potrzeb i mo˙ze on by´c kopiowany wył ˛

acznie w cało´sci, razem z

niniejsz ˛

a stron ˛

a tytułow ˛

a.

background image

1

Operatory arytmetyczne, bitowe i logiczne

(i nie tylko)

Indeksowanie

wska´znik

[

wyra˙zenie

]

Wywołanie funkcji

wyra˙zenie

(

lista wyra˙ze ´n

)

Przyrostkowa inkrementacja

l-warto´s´c

++

Przyrostkowa dekrementacja

l-warto´s´c

- -

Przedrostkowa inkrementacja

++

l-warto´s´c

Przedrostkowa dekrementacja

- -

l-warto´s´c

Negacja bitowa

wyra˙zenie

Negacja logiczna

!

wyra˙zenie

Minus jednoargumentowy

-

wyra˙zenie

Plus jednoargumentowy

+

wyra˙zenie

Mno˙zenie

wyra˙zenie

wyra˙zenie

Dzielenie

wyra˙zenie

/

wyra˙zenie

Modulo

wyra˙zenie

%

wyra˙zenie

Dodawanie

wyra˙zenie

+

wyra˙zenie

Odejmowanie

wyra˙zenie

-

wyra˙zenie

Przesuwanie w lewo

wyra˙zenie

<<

wyra˙zenie

Przesuwanie w prawo

wyra˙zenie

>>

wyra˙zenie

Mniejszy

wyra˙zenie

<

wyra˙zenie

Mniejszy lub równy

wyra˙zenie

<=

wyra˙zenie

Wi ˛ekszy

wyra˙zenie

>

wyra˙zenie

Wi ˛ekszy lub równy

wyra˙zenie

>=

wyra˙zenie

Równy

wyra˙zenie

==

wyra˙zenie

Nierówny

wyra˙zenie

!=

wyra˙zenie

Koniunkcja bitowa

wyra˙zenie

&

wyra˙zenie

Ró˙znica symetryczna

wyra˙zenie

ˆ

wyra˙zenie

Alternatywa bitowa

wyra˙zenie

|

wyra˙zenie

Iloczyn logiczny

wyra˙zenie

&&

wyra˙zenie

Suma logiczna

wyra˙zenie

||

wyra˙zenie

Wyra˙zenie warunkowe

wyra˙zenie

?

wyr.

:

wyr.

Proste przypisanie

l-warto´s´c

=

wyra˙zenie

Przemnó˙z i przypisz

l-warto´s´c

=

wyra˙zenie

Podziel i przypisz

l-warto´s´c

/=

wyra˙zenie

We´z modulo i przypisz

l-warto´s´c

%=

wyra˙zenie

Dodaj i przypisz

l-warto´s´c

+=

wyra˙zenie

Odejmij i przypisz

l-warto´s´c

-=

wyra˙zenie

Przesu ´n w lewo i przypisz

l-warto´s´c

<<

=

wyr.

Przesu ´n w prawo i przypisz

l-warto´s´c

>>

=

wyr.

Koniunkcja bitowa i przypisz

l-warto´s´c

&=

wyra˙zenie

Alternatywa bitowa i przypisz

l-warto´s´c

&=

wyra˙zenie

Ró˙znica bitowa i przypisz

l-warto´s´c

ˆ

=

wyra˙zenie

Operatory zawarte w tej samej cz ˛e´sci tabeli maj ˛

a ten

sam priorytet.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

2

Jaka wy ´swietli si ˛e warto ´s ´c

#

include

<

iostream

>

using namespace std;

int main( )
{

int

x = 1;

cout

<<

++x++

<<

endl

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

2

Jaka wy ´swietli si ˛e warto ´s ´c

#

include

<

iostream

>

using namespace std;

int main( )
{

int

x = 1;

cout

<<

++x++

<<

endl

;

}

Nie wy´swietli ˙zadna warto´s´c, gdy˙z zapis ten jest bł ˛edny.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

3

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1

hhh

hh

h

((

((

(

(

= 0

;

Z1 = Z2 = Z3 = Z4

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

3

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1

hhh

hh

h

((

((

(

(

= 0

;

Z1 = Z2 = Z3 = Z4

;

}

Operacja przypisania domy´slnie realizowana jest tylko mi ˛edzy obiektami tego samego typu. Jej

istotn ˛

a cech ˛

a jest to, ˙ze mo˙ze ona by´c realizowana w sposób kaskadowy (kilka przypisa ´n zło˙zonych

w jedn ˛

a instrukcj ˛e).

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

4

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

=

(

LZespolona Z)

{ re = Z. re;

im = Z. im;

return

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1 = Z2 = Z3 = Z4

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

4

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

=

(

LZespolona Z)

{ re = Z. re;

im = Z. im;

return

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1 = Z2 = Z3 = Z4

;

}

Domy´slna implementacja operacji przypisania jest znacznie bardziej efektywna ni˙z zwykłe przepisy-

wanie warto´sci poszczególnych pól. Dlatego te˙z je˙zeli nie jest to konieczne, to nie nale˙zy reimple-

mentowa´c tej operacji.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

5

Operator przypisania

Z1 = Z2 = Z3 = Z4;

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

5

Operator przypisania

Z1 = Z2 = Z3 = Z4;

Operacja przypisania jest prawostronnie ł ˛

aczna

Z1 = (Z2 = (Z3 = Z4));

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

5

Operator przypisania

Z1 = Z2 = Z3 = Z4;

Operacja przypisania jest prawostronnie ł ˛

aczna

Z1 = (Z2 = (Z3 = Z4));

Z1 = Z2 =

Z3 = Z4;

//

Wykonane zostaje działanie przypisania.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

5

Operator przypisania

Z1 = Z2 = Z3 = Z4;

Operacja przypisania jest prawostronnie ł ˛

aczna

Z1 = (Z2 = (Z3 = Z4));

Z1 = Z2 =

Z3 = Z4;

//

Wykonane zostaje działanie przypisania.

//

Po wykonaniu przypisania zwracana jest referencja

Z1 = Z2 =

Z3;

//

do obiektu po lewej stronie.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

5

Operator przypisania

Z1 = Z2 = Z3 = Z4;

Operacja przypisania jest prawostronnie ł ˛

aczna

Z1 = (Z2 = (Z3 = Z4));

Z1 = Z2 =

Z3 = Z4;

//

Wykonane zostaje działanie przypisania.

//

Po wykonaniu przypisania zwracana jest referencja

Z1 = Z2 =

Z3;

//

do obiektu po lewej stronie.

//

itd. . . .

Z1 =

Z2 = Z3;

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

5

Operator przypisania

Z1 = Z2 = Z3 = Z4;

Operacja przypisania jest prawostronnie ł ˛

aczna

Z1 = (Z2 = (Z3 = Z4));

Z1 = Z2 =

Z3 = Z4;

//

Wykonane zostaje działanie przypisania.

//

Po wykonaniu przypisania zwracana jest referencja

Z1 = Z2 =

Z3;

//

do obiektu po lewej stronie.

//

itd. . . .

Z1 =

Z2 = Z3;

Z1 =

Z2;

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

5

Operator przypisania

Z1 = Z2 = Z3 = Z4;

Operacja przypisania jest prawostronnie ł ˛

aczna

Z1 = (Z2 = (Z3 = Z4));

Z1 = Z2 =

Z3 = Z4;

//

Wykonane zostaje działanie przypisania.

//

Po wykonaniu przypisania zwracana jest referencja

Z1 = Z2 =

Z3;

//

do obiektu po lewej stronie.

//

itd. . . .

Z1 =

Z2 = Z3;

Z1 =

Z2;

Z1 = Z2;

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

6

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

void operator

=

(

LZespolona Z)

{ re = Z. re;

im = Z. im; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1

hhh

hh

h

((

((

(

(

= Z2

hhh

hh

h

((

((

(

(

= Z3 = Z4

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

6

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

void operator

=

(

LZespolona Z)

{ re = Z. re;

im = Z. im; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1

hhh

hh

h

((

((

(

(

= Z2

hhh

hh

h

((

((

(

(

= Z3 = Z4

;

}

Zaniechanie zwracania referencji lub zwrócenie referencji stałej w definicji przeci ˛

a˙zenia operatora

przypisania uniemo˙zliwia kaskadow ˛

a realizacj ˛e tej operacji.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

7

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

=

(

float Arg)

{ re = Arg;

im = 0;

return

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1 = 0

;

Z1 = Z2 = Z3 = Z4 = 0

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

7

Operator przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

=

(

float Arg)

{ re = Arg;

im = 0;

return

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1 = 0

;

Z1 = Z2 = Z3 = Z4 = 0

;

}

Przeci ˛

a˙zenie operatora przypisania dla argumentu odmiennego typu ni˙z klasa, w której to prze-

ci ˛

a˙zenie jest definiowane, nie wyklucza mo˙zliwo´sci korzystania z domy´slnej implementacji operacji

przypisania.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

8

Operator dodania i przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

+=

(

const LZespolona& Z)

{ re += Z. re;

im += Z. im;

return

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1 += Z2 += Z3 += Z4

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

8

Operator dodania i przypisania

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

+=

(

const LZespolona& Z)

{ re += Z. re;

im += Z. im;

return

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1, Z2, Z3, Z4;

Z1 += Z2 += Z3 += Z4

;

}

Operator dodania i przypisania jest równie˙z operatorem prawostronnie ł ˛

acznym. Przekazanie argu-

mentu operacji przez referencj ˛e zapobiega tworzeniu kopii tego obiektu. Stało´s´c referencji pozwala

u˙zy´c jako drugiego argumentu operacji zarówno obiektów stałych, jak te˙z modyfikowalnych.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

9

Operator dodania i przypisania

– warianty implementacji przeci ˛

a˙ze ´

n

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

+=

(

const LZespolona & Z )

{ re += Z. re;

im += Z. im;

return

this ; }

LZespolona operator

+

(

LZespolona Z2 ) const { return Z2 +=

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z w, Z a, Z b;

Z w = Z a + Z b

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

9

Operator dodania i przypisania

– warianty implementacji przeci ˛

a˙ze ´

n

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

+=

(

const LZespolona & Z )

{ re += Z. re;

im += Z. im;

return

this ; }

LZespolona operator

+

(

LZespolona Z2 ) const { return Z2 +=

this ; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z w, Z a, Z b;

Z w = Z a + Z b

;

}

Przeci ˛

a˙zaj ˛

ac wcze´sniej operator dodania i przypisania mo˙zna w prosty i efektywny sposób zapisa´c

definicj ˛e operatora dodawania. Operator ten powinien zwraca´c warto´s´c, a nie referencj ˛e.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

10

Operator odejmowania i przypisania

– warianty implementacji przeci ˛

a˙ze ´

n

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

–=

(

const LZespolona & Z )

{ re –= Z. re;

im –= Z. im;

return

this ; }

LZespolona operator

(

const LZespolona & Z2 ) const

{

return LZespolona(

this ) –= Z2; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z w, Z a, Z b;

Z w = Z a – Z b

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

10

Operator odejmowania i przypisania

– warianty implementacji przeci ˛

a˙ze ´

n

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

–=

(

const LZespolona & Z )

{ re –= Z. re;

im –= Z. im;

return

this ; }

LZespolona operator

(

const LZespolona & Z2 ) const

{

return LZespolona(

this ) –= Z2; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z w, Z a, Z b;

Z w = Z a – Z b

;

}

W przypadku operacji nieprzemiennych nale˙zy zastosowa´c bardziej ogólny schemat definiowania

przeci ˛

a˙zenia operatora, tak jak to ma miejsce dla operacji odejmowania.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

11

Operator mno˙zenia

– warianty implementacji przeci ˛

a˙ze ´

n

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona(float r, float i) { re = r; im = i; }

LZespolona operator

(

const LZespolona & Z2)

const;

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

LZespolona LZespolona::operator

(

const LZespolona & Z2) const

{

return

LZespolona( re

Z2. re – im

Z2. im,

re

Z2. im + im

Z2. re )

;

}

int main( )
{

LZespolona

Z w(0,0), Z a(2,1), Z b(9,3);

Z w = Z a

Z b

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

11

Operator mno˙zenia

– warianty implementacji przeci ˛

a˙ze ´

n

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona(float r, float i) { re = r; im = i; }

LZespolona operator

(

const LZespolona & Z2)

const;

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

LZespolona LZespolona::operator

(

const LZespolona & Z2) const

{

return

LZespolona( re

Z2. re – im

Z2. im,

re

Z2. im + im

Z2. re )

;

}

int main( )
{

LZespolona

Z w(0,0), Z a(2,1), Z b(9,3);

Z w = Z a

Z b

;

}

Wykorzystanie konstruktora mo˙ze ułatwi´c zapis procedury tworzenia ko ´ncowego wyniku, gdy˙z ł ˛

a-

czymy w ten sposób konstrukcj ˛e obiektu i jego inicjalizacj ˛e. W takim przypadku drugi argument

powinien by´c przekazany przez stał ˛

a referencj ˛e, aby unikn ˛

a´c zb ˛ednego kopiowania.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

12

Przed- i przyrostkowe operatory inkrementacji

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

++

( ) { ++ re; ++ im;

return

this ; }

//

++Z

LZespolona

operator

++

(

int )

{

LZespolona Z(

this ); ++

this ; return Z; }

//

Z++

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1;

Z1. re = Z1. im = 2;

Z1++. re += 1

;

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

12

Przed- i przyrostkowe operatory inkrementacji

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona & operator

++

( ) { ++ re; ++ im;

return

this ; }

//

++Z

LZespolona

operator

++

(

int )

{

LZespolona Z(

this ); ++

this ; return Z; }

//

Z++

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1;

Z1. re = Z1. im = 2;

Z1++. re += 1

;

hhh

hh

h

((

((

(

(

}

Rozró˙znienie operatora przed- od przyrostkowego jest realizowane przez wprowadzenie parame-

tru typu

int. Wskazane jest, aby przeci ˛

a˙zenie operatora przedrostkowego zwracało referencj ˛e do

obiektu, za´s przyrostkowego kopi ˛e. Jednak nie jest to obowi ˛

azkowe.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

13

Operatory – i +

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona( float r = 0, float i = 0 ): re(r), im(i) { }
LZespolona operator

+

( )

const { return

this ; }

LZespolona operator

( )

const { return LZespolona(– re,– im); }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1;

Z1. re = Z1. im = 2;

(–Z1). re += 1;

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

13

Operatory – i +

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona( float r = 0, float i = 0 ): re(r), im(i) { }
LZespolona operator

+

( )

const { return

this ; }

LZespolona operator

( )

const { return LZespolona(– re,– im); }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1;

Z1. re = Z1. im = 2;

(–Z1). re += 1;

hhh

hh

h

((

((

(

(

}

Implementacja przeci ˛

a˙ze ´n operatorów powinna, o ile to jest tylko mo˙zliwe, by´c zgodna z intuicyjnym

rozumieniem operatorów. Przeci ˛

a˙zenia, które nie zmieniaj ˛

a stanu obiektu, powinny by´c definiowane

jako metody “stałe”.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

14

Operatory – i +

class LZespolona { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

re, im;

LZespolona( float r = 0, float i = 0 ): re(r), im(i) { }
const LZespolona & operator

+

( )

const { return

this ; }

LZespolona operator

( )

const { return LZespolona(– re,– im); }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

LZespolona

Z1;

Z1. re = Z1. im = 2;

(–Z1). re += 1;

hhh

hh

h

((

((

(

(

}

Implementacja przeci ˛

a˙ze ´n operatorów powinna, o ile to jest tylko mo˙zliwe, by´c zgodna z intuicyjnym

rozumieniem operatorów. Przeci ˛

a˙zenia, które nie zmieniaj ˛

a stanu obiektu, powinny by´c definiowane

jako metody “stałe”.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

15

Problem z priorytetami

class Wektor3f { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

x, y, z;

Wektor3f operator

(

const Wektor3f & W2) const; // Iloczyn wektorowy

float operator

&

(

const Wektor3f & W2) const

;

// Iloczyn skalarny

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . .

int main( )
{

Wektor2f

V1, V2;

if (

hhh

hhh

hhh

((

((

((

((

(

V1 & V2

>

0

) {

. . . }

//

Zwyczajowy zapis:

V

1

·V

2

> 0

if (

(V1 & V2)

>

0

) {

. . . }

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

15

Problem z priorytetami

class Wektor3f { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float

x, y, z;

Wektor3f operator

(

const Wektor3f & W2) const; // Iloczyn wektorowy

float operator

&

(

const Wektor3f & W2) const

;

// Iloczyn skalarny

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . .

int main( )
{

Wektor2f

V1, V2;

if (

hhh

hhh

hhh

((

((

((

((

(

V1 & V2

>

0

) {

. . . }

//

Zwyczajowy zapis:

V

1

·V

2

> 0

if (

(V1 & V2)

>

0

) {

. . . }

}

Dobór operatorów do realizacji poszczególnych operacji powinien by´c mo˙zliwie zbli˙zony do ich pier-

wotnego znaczenia. Jednak z drugiej strony wzajemne priorytety operatorów powinny odpowiada´c

priorytetom implementowanych operacji. Nie zawsze te wymagania daj ˛

a si ˛e pogodzi´c.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

16

Operator indeksuj ˛

acy

class Wektor3f { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float x, y, z;

float operator [ ] ( unsigned int ind ) const

{

return ind ? ind == 1 ? y : z : x; }

float & operator [ ] ( unsigned int ind )

{

return ind ? ind == 1 ? y : z : x; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

Wektor2f

V1, V2;

V1.x = V2[2]

;

V1[2] = V2.z

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

16

Operator indeksuj ˛

acy

class Wektor3f { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

float x, y, z;

float operator [ ] ( unsigned int ind ) const

{

return ind ? ind == 1 ? y : z : x; }

float & operator [ ] ( unsigned int ind )

{

return ind ? ind == 1 ? y : z : x; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

Wektor2f

V1, V2;

V1.x = V2[2]

;

V1[2] = V2.z

;

}

Przeci ˛

a˙zenie operator indeksuj ˛

acego pozwala na dost ˛ep do tych samych struktur na dwa sposoby.

Pierwszy z nich pozwala odwoła´c do konkretnych pól po nazwie, drugi za´s pozwala widzie´c cał ˛

a

struktur ˛e jako tablic ˛e. Podwójne przeci ˛

a˙zenie pozwala na realizacj ˛e zarówno odczytu jak te˙z zapisu.

Przedstawiona implementacja przeci ˛

a˙ze ´n nie zapewnia pełnej kontroli zakresu.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

17

Operator indeksuj ˛

acy

class Wektor3f { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

union {

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float

Tab[3];

struct { float x, y, z; };

}

;

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float operator [ ] ( unsigned int ind ) const { return

Tab[ ind ]; }

float & operator [ ] ( unsigned int ind ) { return

Tab[ ind ]; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

Wektor2f

V1, V2;

V1.x = V2[2]

;

V1[2] = V2.z

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

17

Operator indeksuj ˛

acy

class Wektor3f { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

union {

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float

Tab[3];

struct { float x, y, z; };

}

;

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float operator [ ] ( unsigned int ind ) const { return

Tab[ ind ]; }

float & operator [ ] ( unsigned int ind ) { return

Tab[ ind ]; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

Wektor2f

V1, V2;

V1.x = V2[2]

;

V1[2] = V2.z

;

}

Wykorzystanie w definicji nienazwanej unii zapewnia realizacj ˛e znacznie bardziej efektywnego do-

st ˛epu na ró˙zne sposoby do tego samego obszaru pami ˛eci.

(Niestety niedopuszczalne w ANSI C++ :(

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

18

Operator indeksuj ˛

acy

class Wektor3f { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

union {

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float

Tab[3];

struct { float

x, y, z; };

}

;

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

union {

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

struct { float x, y, z; };

}

;

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float operator [ ] ( unsigned int ind ) const { return

Tab[ ind ]; }

float & operator [ ] ( unsigned int ind ) { return

Tab[ ind ]; }

float Norma( ) const { return sqrt( x

x + y

y + z

z); }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

18

Operator indeksuj ˛

acy

class Wektor3f { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

union {

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float

Tab[3];

struct { float

x, y, z; };

}

;

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

public :

union {

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

struct { float x, y, z; };

}

;

//

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float operator [ ] ( unsigned int ind ) const { return

Tab[ ind ]; }

float & operator [ ] ( unsigned int ind ) { return

Tab[ ind ]; }

float Norma( ) const { return sqrt( x

x + y

y + z

z); }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Unie nienazwane pozwalaj ˛

a odwoływa´c si ˛e do tego samego obszaru pami ˛eci nie tylko w ró˙zny spo-

sób, ale równie˙z pozwalaj ˛

a tworzy´c konstrukcje definiuj ˛

ace dost ˛epno´s´c ze wzgl ˛edu na zadany spo-

sób odwołania do pami ˛eci. Nie nale˙zy jednak nadu˙zywa´c tego mechanizmu do tworzenia wielu

synonimów nazw pól.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

19

Operator funkcyjny

class Macierz3x3f { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float

Tab[3][3];

public :

float operator ( ) (unsigned int i, unsigned int j) const { return

Tab[ i ][ j ]; }

float& operator ( ) (unsigned int i, unsigned int j) { return

Tab[ i ][ j ]; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

Macierz3x3f M;

M(1,2) = 5

;

M(1,1) = M(1,2)

;

}

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

19

Operator funkcyjny

class Macierz3x3f { //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

float

Tab[3][3];

public :

float operator ( ) (unsigned int i, unsigned int j) const { return

Tab[ i ][ j ]; }

float& operator ( ) (unsigned int i, unsigned int j) { return

Tab[ i ][ j ]; }

}; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

int main( )
{

Macierz3x3f M;

M(1,2) = 5

;

M(1,1) = M(1,2)

;

}

Przeci ˛

a˙zenie operatorów wywołania funkcji pozwala na organizacj ˛e wygodnego dost ˛epu do we-

wn ˛etrznych struktur tablicowych.

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

20

Pytania i ´cwiczenia

1. Dany jest fragment kodu:

class ProstaKlasa {

int Pole;

public:

void Zmien(int Wart) { Pole = Wart; }

};

int main()

{

ProstaKlasa

const Ob;

ProstaKlasa

&Ref = Ob;

. . .

A. Czy powy˙zej w poprawny sposób utworzona została referencja do obiektu

Ob

?

B. Je˙zeli nie, to jak nale˙zy to zapisa´c aby operacja była poprawna (nie zmieniaj ˛

ac

deklaracji referencji

Ref

)?

C. Je˙zeli tak, to jak nale˙zy to zapisa´c aby uniemo˙zliwi´c tak ˛

a operacj ˛e?

D. Czy po utworzeniu referencji

Ref

b ˛edzie si ˛e mo˙zna poprzez ni ˛

a odwoła´c do me-

tody

Zmien

?

Przeci ˛

a˙zanie operatorów (odsłona druga)

background image

21

Pytania i problemy

2. Dana jest definicja klasy

LZespolona:

class LZespolona {

public :

float

re, im;

LZespolona operator = ( LZespolona Z)

{ re = Z. re;

im = Z. im;

return

this ; }

};

Niech b ˛ed ˛

a dane zmienne:

LZespolona Z1, Z2, Z3. Czy dwie poni˙zsze operacje daj ˛

a taki

sam wynik?

Z1 = Z2 = Z3;

(Z1 = Z2) = Z3;

Je˙zeli tak, to jaki zachodzi zwi ˛

azek mi ˛edzy warto´sciami zmiennych? Je˙zeli natomiast nie, to

co nale˙zy zrobi´c, aby wynik był taki sam?

3. Dana jest definicja klasy:

class LZespolona {

public :

float

re, im;

LZespolona & operator ++ (int) { ++ re; ++ im; return

this ; }

};

Czy działanie przedstawione poni˙zej jest prawidłowo zapisane (w sensie składni)?

LZespolona

Z1;

Z. re = Z. im = 2; ++Z. re += 1;

Je˙zeli tak, to jaki jest wynik działania? Je˙zeli nie, to co nale˙zy zrobi´c, aby było ono poprawne.

Przeci ˛

a˙zanie operatorów (odsłona druga)


Wyszukiwarka

Podobne podstrony:
JAVA 05 operatory
JS 05 Operatory Logiczne, Programowanie, instrukcje - teoria
05 Operatory, wyrażenia i instrukcje
PRZEPISY I PROCEDURY OPERATORSKIE cz2
05 Operatory, wyrażenia i instrukcje
Simak, Clifford D Aliens for Neighbors 05 Operation Stinky
05 Operatory i wyrażenia
mechanik operator pojazdow i maszyn rolniczych 723[03] o1 05 u
prez UZ 4FD Iseria 05 06
mechanik operator pojazdow i maszyn rolniczych 723[03] z2 05 n
mechanik operator pojazdow i maszyn rolniczych 723[03] z2 05 u
operator maszyn i urzadzen odlewniczych 812[03] z2 05 n
operator urzadzen przemyslu szklarskiego 813[02] z2 05 n
operator urzadzen przemyslu ceramicznego 813[01] o1 05 n
operator urzadzen przemyslu szklarskiego 813[02] z2 05 u
asystent operatora dzwieku 313[06] o1 05 u
asystent operatora dzwieku 313[06] o1 05 n

więcej podobnych podstron