Programowanie Obiektowe
(język C++)
vs
operatory jako metody
Wykład 4.
Tomasz Marks - Wydział MiNI PW
-1-
Tomasz Marks - Wydział MiNI PW
-2-
Operator jako funkcja vs metoda [0]
Operator jako funkcja vs metoda [1]a
// operator + / funkcja zaprzyjaźniona (definicja)
CMPLX operator+ ( CMPLX a, CMPLX b )
class CMPLX
{
{
CMPLX c;
......................................
c.Re = a.Re + b.Re; c.Im = a.Im + b.Im;
......................................
return c;
public:
}
......................................
// operatory dwuargumentowe ( metody )
CMPLX operator- ( CMPLX );
......................................
// operator - / metoda (definicja)
CMPLX CMPLX::operator- ( CMPLX b ) const
......................................
{
// operatory dwuargumentowe ( funkcje zaprzyjaźnione )
CMPLX c;
friend CMPLX operator+ ( CMPLX, CMPLX );
c.Re = Re - b.Re; c.Im = Im - b.Im;
......................................
return c;
}
};
Tomasz Marks - Wydział MiNI PW
-3-
Tomasz Marks - Wydział MiNI PW
-4-
Operator jako funkcja vs metoda [1a]
Operator jako funkcja vs metoda [1b]
// operator + / funkcja zaprzyjaźniona (definicja)
// operator + / funkcja zaprzyjaźniona (definicja)
CMPLX operator+ ( CMPLX a, CMPLX b )
CMPLX operator+ ( CMPLX a, CMPLX b )
{
{
CMPLX c ( a.Re + b.Re, a.Im + b.Im );
return CMPLX ( a.Re + b.Re, a.Im + b.Im );
return c;
}
}
// operator - / metoda (definicja)
// operator - / metoda (definicja)
CMPLX CMPLX::operator- ( CMPLX b ) const
CMPLX CMPLX::operator- ( CMPLX b ) const
{
{
CMPLX c ( Re - b.Re, Im - b.Im );
return CMPLX ( Re - b.Re, Im - b.Im );
return c;
}
}
Tomasz Marks - Wydział MiNI PW
-5-
Tomasz Marks - Wydział MiNI PW
-6-
Operator jako funkcja vs metoda [2]
Przypomnienie ...
// operator + / metoda (definicja)
CMPLX CMPLX::operator+ ( CMPLX b ) const
{
CMPLX c;
c.Re = Re + b.Re;
• Każda metoda niestatyczna ma dostęp
c.Im = Im + b.Im;
do wskaźnika na obiekt, na rzecz
return c;
}
którego zostanie wywołana.
// RÓWNOWAśNE
// operator + / metoda (definicja)
• Wskaźnik ten wyrażany jest słowem
CMPLX CMPLX::operator+ ( CMPLX b ) const
{
kluczowym this.
CMPLX c;
c.Re = this->Re + b.Re;
c.Im = (*this).Im + b.Im;
return c;
}
Tomasz Marks - Wydział MiNI PW
-7-
Tomasz Marks - Wydział MiNI PW
-8-
Operator jako funkcja vs metoda [3]
Operator jako funkcja vs metoda [4]
CMPLX A, B, C;
CMPLX A, B, C;
// operator + / funkcja zaprzyjaźniona (użycie)
C = A + B;
// o.k.
// operator + / funkcja zaprzyjaźniona (użycie)
C = A + 5.2; // o.k. równowa
C = A + B;
żne C = operator+ ( A, 5.2 );
// równowa
// albo
żne C = operator+ ( A, CMPLX ( 5.2 ) );
C = operator+ ( A, B );
C = 5.2 + A; // o.k. równoważne C = operator+ ( 5.2, A );
// równoważne C = operator+( CMPLX ( 5.2 ), A );
// operator - / metoda (u
// operator - / metoda (u
życie)
życie)
C = A - B;
// o.k.
C = A - B;
// albo
C = A - 5.2; // o.k. równowa
C = A.operator- ( B );
żne C = A.operator- ( 5.2 );
// równoważne C = A.operator- ( CMPLX ( 5.2 ) );
C = 5.2 - A; // ŹLE równoważne C = (5.2).operator- ( A );
// metoda musi działać na rzecz obiektu klasy!!!
Tomasz Marks - Wydział MiNI PW
-9-
Tomasz Marks - Wydział MiNI PW
-10-
Operator przypisania dla klasy CMPLX [1]
Operator przypisania dla klasy CMPLX [2]
N.p.
Jeż eli zdecydujemy się zadeklarować własny operator przypisania CMPLX& CMPLX::operator= ( const CMPLX& rhs )
{
Re = rhs.Re;
Im = rhs.Im;
class CMPLX
return *this;
{
}
……………………….
albo
public:
CMPLX& operator= ( const CMPLX& );
CMPLX& CMPLX::operator= ( const CMPLX& rhs )
……………………….
{
if ( this != &rhs )
};
{
Re = rhs.Re;
Im = rhs.Im;
}
to musimy podać jego implementację (definicję ).
return *this;
}
Tomasz Marks - Wydział MiNI PW
-11-
Tomasz Marks - Wydział MiNI PW
-12-
Jeszcze o użyciu słowa kluczowego this
Operator indeksowy dla klasy CMPLX [1]
class CMPLX
CMPLX::CMPLX ( double re, double im )
{
……………………….
{
public:
Re = re; Im = im;
// o.k.
// zamiast 4 prymitywnych metod dostępowych
}
double getRe () const { return Re; }
double getIm () const { return Im; }
CMPLX::CMPLX ( double Re, double Im )
void setRe ( double re ) { Re = re; }
{
void setIm ( double im ) { Im = im; }
Re = Re; Im = Im;
// ŹLE: nazwy parametrów
// lub 2 metod referencyjnych
} // przesłaniają nazwy pól double& refRe () { return Re; }
double& refIm () { return Im; }
CMPLX::CMPLX ( double Re, double Im )
{
// można zdefiniować 1 metodę opisującą operator indeksowy
this->Re = Re; this->Im = Im;
// o.k.
double& operator [ ] ( int i ) { return i ? Im : Re; }
……………………….
}
};
Tomasz Marks - Wydział MiNI PW
-13-
Tomasz Marks - Wydział MiNI PW
-14-
Operator indeksowy dla klasy CMPLX [2]
Operatory ++ i -- dla klasy CMPLX
class CMPLX
{
{
……………………….
……………………….
CMPLX A, B, C, T[5];
// funkcje zaprzyjaźnione
……………………….
friend CMPLX& operator++ ( CMPLX& );
// przedrostkowy
friend CMPLX operator++ ( CMPLX&, int ); // przyrostkowy
C[0] = max ( A[0], A[1] ); // wyraża: C.Re = max ( A.Re, A.Im );
……………………….
public:
C[1] = B[1] - A[0]; // wyraża:
C.Im = B.Im - A.Re;
……………………….
// metody
T[4][0] = 2.5;
// wyraża:
T[4].Re = 2.5;
CMPLX& operator-- ( );
// przedrostkowy
CMPLX operator-- ( int );
// przyrostkowy
……………………….
};
Tomasz Marks - Wydział MiNI PW
-15-
Tomasz Marks - Wydział MiNI PW
-16-
// funkcje zaprzyjaźnione
CMPLX& operator++ ( CMPLX& z )
// przedrostkowy
{
z.Re++;
return z;
// zwraca referencję
}
CMPLX operator++ ( CMPLX& z, int )
// przyrostkowy
{
CMPLX old( z.Re++, z.Im );
return old;
// zwraca nowy obiekt
}
new i delete
// metody
CMPLX& CMPLX::operator-- ( )
// przedrostkowy
{
--Re;
return *this;
// zwraca referencję
}
CMPLX CMPLX:: operator-- ( int )
// przyrostkowy
{
CMPLX old( Re--, Im );
return old;
// zwraca nowy obiekt
}
Tomasz Marks - Wydział MiNI PW
-17-
Tomasz Marks - Wydział MiNI PW
-18-
PRZYPOMNIENIE: Operatory new i delete [1]
Operatory new i delete [2]
int A;
CMPLX A;
static int B;
static CMPLX B;
extern int C;
extern CMPLX C;
void fun ( int a )
void fun ( CMPLX a )
{
{
int b, *p, *q;
CMPLX b, *p, *q;
static int c;
static CMPLX c;
extern int D;
extern CMPLX D;
b = a;
b = a;
p = new int;
// utworzenie zmiennej *p (wartość 0)
p = new CMPLX; // utworzenie obiektu *p (konstruktor bezparametrowy) q = new int ( 4 ); // utworzenie zmiennej *q (wartość 4)
q = new CMPLX ( 2.5, 3.5 );
// utworzenie obiektu *q (konstruktor 2-parametrowy)
*p = 5; *q = 6;
*p = 5; *q = 6;
delete p;
// zmienna *p "znika"
delete p; // obiekt *p "znika" (destruktor)
return;
return;
// zmienna *q pozostanie niedostępny
// obiekt *q pozostanie niedostępny
}
}
Tomasz Marks - Wydział MiNI PW
-19-
Tomasz Marks - Wydział MiNI PW
-20-
Operatory new i delete [4]
void fun ( CMPLX a )
{
int tab_i [ 5 ], *p;
Operator new moż e też przyjmować inne postaci, n.p.
CMPLX tab_C [ 5 ], *q;
Class *p, *q;
p = new int [ 5 ]; // utworzenie tablicy o 5 elementach typu int
//
p[0], p[1], p[2], p[3], p[4]
……………………….
q = new CMPLX [ 5 ]; // utworzenie tablicy o 5 elementach typu CMPLX
p = new ( Placement ) Class; // utworzenie obiektu
//
q[0], q[1], q[2], q[3], q[4]
q = new ( Placement ) Class [ 5 ]; // utworzenie tablicy obiektów
……………………….
……………………….
……………………….
delete [ ] p;
// wszystkie elementy (zmienne)
// tablicy wskazywanej przez p "znikają"
gdzie Placement jest listą argumentów okreś lonych w przeciąż eniu operatora new dla klasy Class.
delete [ ] q; // wszystkie elementy (obiekty)
// tablicy wskazywanej przez q "znikają" (destruktor)
Tego tematu nie bę dziemy rozwijać .
return;
}
Tomasz Marks - Wydział MiNI PW
-21-
Tomasz Marks - Wydział MiNI PW
-22-
PRZYPOMNIENIE: Zmienne globalne / lokalne
int A; // definicja zmiennej globalnej A
static int B; // definicja zmiennej B lokalnej w treści pliku extern int C; // deklaracja zmiennej globalnej C zdefiniowanej globalne / lokalne
// być może w innym pliku
void fun ( int a ) // parametr a jest zmienną lokalną w treści funkcji
{
int b, *p, *q; // definicja zmiennych b, p, q lokalnych w treści funkcji static int c; // definicja zmiennej c lokalnej w treści funkcji extern int D; // deklaracja zmiennej globalnej D zdefiniowanej statyczne / dynamiczne
// być może w innym pliku
b = a;
p = new int;
// utworzenie zmiennej *p (wartość 0)
q = new int(4); // utworzenie zmiennej *q (wartość 4)
*p = 5; *q = 6;
delete p; // zmienna *p "znika"
return;
// zmienne a, b, p, q "znikają",
// zmienna c zachowuje swoją wartość
// zmienna *q zachowuje swoją wartość, ale pozostanie niedostępna
}
Tomasz Marks - Wydział MiNI PW
-23-
Tomasz Marks - Wydział MiNI PW
-24-
PRZYPOMNIENIE: Zmienne statyczne / dynamiczne
Obiekty globalne / lokalne
int A; // statyczna (wartość 0)
CMPLX A; // definicja obiektu globalnego A
static int B; // statyczna (wartość 0)
static CMPLX B; // definicja obiektu B lokalnego w treści pliku extern int C; // statyczna (wartość nieznana)
extern CMPLX C; // deklaracja obiektu globalnego C zdefiniowanego
// być może w innym pliku
void fun ( int a ) // dynamiczna (automatyczna) (wartość okr. argumentem) void fun ( CMPLX a ) // parametr a jest obiektem lokalnym w treści funkcji
{
{
int b, *p, *q; // dynamiczne (automatyczne) (wartości nieokreślone) CMPLX b, *p, *q; // definicja obiektu b i zmiennych p, q lokalnych w treści funkcji static int c; // statyczna (wartość 0 przy pierwszym wywołaniu)
static CMPLX c; // definicja obiektu c lokalnego w treści funkcji extern int D; // statyczna (wartość nieznana)
extern CMPLX D; // deklaracja obiektu globalnego D zdefiniowanego
// być może w innym pliku
b = a;
b = a;
p = new int;
// dynam. (kontrolowana) (wartość 0)
p = new CMPLX;
// utworzenie obiektu *p (konstruktor bezparametrowy)
q = new int(4); // dynam. (kontrolowana) (wartość 4)
q = new CMPLX(2.5, 3.5);
// utworzenie obiektu *q (konstruktor 2-parametrowy)
*p = 5; *q = 6;
*p = 5; *q = 6; // równoważne: *p = CMPLX(5,0); *q = CMPLX(6,0); delete p; // zmienna kontrolowana *p "znika"
delete p; // obiekt *p "znika"
return;
// zmienne automatyczne a, b, p, q "znikają",
return;
// obiekty a, b, p, q "znikają",
// zmienna statyczna c zachowuje swoją wartość
// obiekt c zachowuje swoją wartość
// zmienna kontr. *q zachowuje swoją wartość, ale pozostanie niedostępna
// obiekt *q zachowuje swoją wartość, ale pozostanie niedostępny
}
}
Tomasz Marks - Wydział MiNI PW
-25-
Tomasz Marks - Wydział MiNI PW
-26-
Obiekty statyczne / dynamiczne
CMPLX A; // statyczny (konstruktor bezparametrowy)
static CMPLX B; // statyczny (konstruktor bezparametrowy)
extern CMPLX C; // statyczny (konstruktor nieznany)
void fun ( CMPLX a ) // dynamiczny (automatyczny) (konstruktor kopiujący)
{
CMPLX b, *p, *q; // dynamiczny (automatyczny) b (konstruktor bezparametrowy)
// dynamiczne (automatyczne) p, q (wartości nieokreślone)
static CMPLX c; // statyczny (konstruktor bezparametrowy)
extern CMPLX D; // statyczny (konstruktor nieznany)
Koniec wykładu 4.
b = a;
p = new CMPLX;
// dynam. (kontrolowany) (wart. okreslona konstruktorem bezp.)
q = new CMPLX(2.5,3.5); // dynam. (kontrolowany) (wart. okreslona konstr. 2-par.)
*p = 5; *q = 6;
delete p; // obiekt kontrolowany *p "znika"
return;
// obiekty automatyczne a, b i zmienne automatyczne p, q "znikają",
// obiekt statyczny c zachowuje swoją wartość
// obiekt kontr. *q zachowuje swoją wartość, ale pozostanie niedostępny
}
Tomasz Marks - Wydział MiNI PW
-27-
Tomasz Marks - Wydział MiNI PW
-28-