2.1 Definicja, deklaracja, wywołanie funkcji.... 1 2.2 Funkcje inline... 4 2.3 Przekazanie do argumentu funkcji wartości, adresu zmiennej.... 5 2.4 Wskaźniki do funkcji... 8 2.5 Przeładowanie funkcji... 9 2.6 Przeładowanie operatorów.... 11 2.1 Definicja, deklaracja, wywołanie funkcji. <zwracanytyp> nazwafunkcji(<typarg1> <nazwaarg1>, <typarg2> <nazwaarg2>, ) <instrukcje>; Przykład 1. Deklaracja, definicja, wywołanie funkcji (w02-01-funkcjedefinicja.cpp). int f(int, int); // deklaracaja funkcji int w = 0; w = f(10, 20); // wywołanie funkcji cout << w << endl; // definicja funkcji int f(int x, int y) int w = x + y; return w; Przykład 2. Inicjowanie argumentu funkcji. void f(char * pc = "tekst") 1
Przykład 3. Deklaracja, definicja, wywołanie metody (w02-03a-metody.cpp). class A int f(int, int); ; // deklaracaja metody A a; int w = 0; w = a.f(10, 20); cout << w << endl; // wywołanie metody // definicja metody int A::f(int x, int y) int w = x + y; return w; Przykład 4. Metody const nie mogą modyfikowć atrybutów klasy (w02-03b-metodyconst.cpp). #include<iostream> class A A(int x) : i(x) void f1() const; void f2(a *p) const; private: int i; ; void A::f1() const // i = 400; // błąd, modyfikacja obiektu i cout << this->i << endl; void A::f2(A *p) const p->i = 300; p->i++; cout << p->i << endl; A a(100); a.f1(); a.f2(&a); 2
Przykład 5. Metody static mogą być wywołane bez obiektu (w02-03c-metodystatic.cpp). class A static void f(); void g(); ; void A:: f() cout << " static f() " << endl; void A:: g() cout << " g() " << endl; A::f(); // A::g(); // błąd, metoda g() nie jest statyczna 3
2.2 Funkcje inline. inline <zwracanytyp> nazwafunkcji(<typarg1> <nazwaarg1>, <typarg2> <nazwaarg2>, ) <instrukcje>; Własności: 1. Funkcje inline nie mogą być wbudowane w biblioteki.lib czy.dll. To kompilator wstawia kod w miejsce wywołania funkcji a nie linker. 2. Definicje funkcji inline mogą być w plikach nagłówkowych.h. 3. Metody definiowane w klasach są zawsze inline. 4. Metody definiowane poza klasą są inline jeżeli użyje się polecenia inline, np.: inline <zwracanytyp> nazwaklasy::nazwafunkcji(<typargumentu> <nazwaargumentu>, ) Przykład 1. Definicja funkcji inline (w02-04-inlinefunkcje.cpp). inline int f(int); int x =10; int w; w = f(x); w = f(f(x)); w = f(w); int f(int i) int k = i * i; return k; Przykład 2. Makro zawsze jest inline. Makro MAX i odpowiadająca jej funkcja inline. #define MAX(a, b) ((a) > (b)? (a) : (b)) inline int max(int a, int b) return a > b? a : b; 4
Przykład 3. Metody definiowane w klasach są inline (w02-05-inlinemetody.cpp). class A // implementacja metody w klasie, jawana postac inline void f() cout << "f() w A " << endl; // deklaracja metody, kompilator wstawi wywolanie funkcji, // funkcja zdefiniowana jest w innym miejscu void g(); ; // deklaracja metody, kompilator wstawi korpus funkcji // czyli pelną implementację funkcji void h(); // implementacja metody poza klasa void A::g() cout << "g() w A " << endl; // implementacja metody jako inline inline void A::h() cout << "h() w A " << endl; 2.3 Przekazanie do argumentu funkcji wartości, adresu zmiennej. Przykład 1. Przekazanie do argumentu funkcji wartości zmiennej (w02-06a-przekazaniewartosci.cpp). int f(int x) x = x*x; return x; int y = 10; cout << "y w main() przed = " << y << endl; f(y); cout << "y w main() po = " << y << endl; y w main() przed = 10 y w main() po = 10 5
Przykład 2. Przekazanie do argumentu funkcji adresu zmiennej (poprzez referencje, w02-06b-przekazanieadresu- Referencja.cpp). int f(int &x) x = x*x; return x; int y = 10; cout << "y w main() przed = " << y << endl; cout << "f(y) cout << "y w main() po = " << f(y) << endl; = " << y << endl; y w main() przed = 10 f(y) = 100 y w main() po = 100 Przykład 3. Przekazanie do argumentu funkcji adresu zmiennej (poprzez wskaźnik, w02-06c-przekazanieadresu- Wskaznik.cpp). int f(int *x) *x = *x * (*x); return *x; int y = 10; int *py =&y; cout << "y w main() przed = " << y << endl; cout << "f(py) cout << "y w main() po cout << "f(&y) cout << "y w main() po = " << f(py) << endl; = " << y << endl << endl; = " << f(&y) << endl; = " << y << endl; 6
y w main() przed = 10 f(py) = 100 y w main() po = 100 f(&y) = 10000 y w main() po = 10000 Uwaga: Jeżeli funkcję f() zdefiniujemy następująco int f(int &x) return x*x; int f(int *x) return *x * (*x);, to wartość zmiennej y nie zmieni się po wywołaniu funkcji. 7
2.4 Wskaźniki do funkcji. Przykład 1. Wskaźnik do funkcji (w02-07-wskaznikidofunkcji.cpp). int (*pfun)(int); int fun1(int); int fun2(int); pfun = &fun1; cout << "fun1(10) = " << fun1(10) << endl; cout << "pfun(10) = " << pfun(10) << endl; pfun = fun2; cout << "fun2(20) = " << fun2(20)<< endl; cout << "pfun(20) = " << pfun(20) << endl; int fun1(int x) cout<< "fun1(int), "; return (x * x); int fun2(int x) cout << "fun2(int), "; return 2 * x; fun1(int), fun1(10) = 100 fun1(int), pfun(10) = 100 fun2(int), fun2(20) = 40 fun2(int), pfun(20) = 40 Przykład 2. Adres funkcji (w02-08-adresfunkcji.cpp). int fun1(int x) return x; void fun2(int x) cout << "fun2, x = " << x << endl; cout <<"&fun1 = " << (long)&fun1 << endl; cout <<"&fun2 = " << (long)&fun2 << endl; &fun1 = 18748522 &fun2 = 18747797 8
2.5 Przeładowanie funkcji Definicja. Sygnatura funkcji jest to nazwa funkcji, liczba argumentów, uporządkowany zbiór typów argumentów funkcji, klasa lub obszar nazw do którego funkcja należy. Uwaga: Funkcje mają różne typy jeżeli ich sygnatury są różne. Obiekty funkcyjne (function objects) mogą mieć różny typ nawet wtedy, gdy mają takie same sygnatury. Definicja. przeładowanie funkcji (function overloading). Funkcja jest przeładowana, jeżeli istnieje inna funkcja o takiej samej nazwie ale różnej sygnaturze. Przeładowane funkcje, operatory nazywane są funkcjami, operatorami polimorficznymi. Przykład 1. Sygnatura funkcji. Sygnatura funkcji g(): nazwa g, lista argumentów (char, int, double). int g(char x, int y, double z) Sygnatura funkcji f(): nazwa f, lista argumentów (int, int), klasa A. int A::f(int x, int y) Przykład 2. Przeładowanie funkcji (w02-09-przeladowaniefunkcji.cpp). void funkcja() cout << "funkcja()" << endl; void funkcja(int i) cout << "funkcja(int) = " << i << endl; void funkcja(double d) cout << "funkcja(double) = " << d << endl; void funkcja(char pct[]) cout << "funkcja(char[]) = " << pct << endl; void funkcja(int i1, int i2) cout << "funkcja(int,int) = " << i1 * i2 << endl; void main () funkcja(); funkcja(5); funkcja(0.123); funkcja("tekst"); funkcja(2,5); 9
Przykład 2. Funkcje tego samego typu, tzn. te funkcje nie są przeładowane. void funkcja(int ix) int funkcja(int ix) return 0; const void funkcja(int ix) void funkcja(const int ix) Przykład 3. Przeładowanie funkcji wskaźnikiem (w02-10-przeladowaniewsk.cpp). #include <string> void f(string x) cout <<"f(int), x = " << x << endl; void f(string * px) cout <<"f(string*), *px = " << *px << endl; string s = "abc"; string * ps = &s; string * p = new string("xyz"); f(s); f(ps); f(p); f(*p); Przykład 4. Przeładowanie metod (w02-11-przeladowaniemetod.cpp). class A A(): i(0), ci(0) int f() cout << "f()" << endl; return i; int f() const cout << "f() const" << endl; return ci; int g() const cout << "g() const" << endl; return i; private: int i; const int ci; ; A a; a.f(); a.g(); const A ca; ca.f(); ca.g(); 10
2.6 Przeładowanie operatorów. Przykład. Przeładowanie operatora + (w02-12-przeladowanieop+.cpp). #include<iostream> class A A()i=0; A(int x): i(x) ~A() int PokAtr() const return i; A operator+ (const A &); protected: int i; ; A A:: operator+ (const A &ra) return (i + ra.i); A a, a1(100), a2(200); cout <<"a1.i = " << a1.pokatr() << endl; cout <<"a2.i = " << a2.pokatr() << endl; a = a1 + a2; cout <<"a1 + a2 = " << a.pokatr() << endl; a1.i = 100 a2.i = 200 a1 + a2 = 300 11
Przykład. Przeładowanie operatora = (w02-13-przeladowanieop=.cpp). class A A(); A(int); ~A(); int GetAtr() const; void SetAtr(int); A & operator = (const A &); private: int *p; ; A::A() p = new int(0); cout << "A()" << endl; A::A(int x) p = new int(x); cout << "A(int)" << endl; A::~A() delete p; cout << "~A()" << endl; int A::GetAtr() const return *p; void A::SetAtr(int x) *p = x; A & A::operator=(const A & r) if (this == &r) return *this; *p = r.getatr(); return *this; A a; A b(900); cout << "a= "<< a.getatr() << endl; cout << "b= "<< b.getatr() << endl; a = b; cout << "a= "<< a.getatr() << endl; A() A(int) a= 0 b= 90 a= 90 a= 80 ~A() ~A() b.setatr(800); a = b; cout << "a= "<< a.getatr() << endl; 12