200 likes | 326 Views
Kurs języka C++ – wykład 3 (17.03.2014). Przenoszenie Składowe statyczne Funkcje wbudowane Funkcje zaprzyjaźnione. Spis treści. Semantyka przenoszenia Składowe statyczne static Funkcje i metody wbudowane inline. Semantyka przenoszenia.
E N D
Kurs języka C++ – wykład 3 (17.03.2014) PrzenoszenieSkładowe statyczneFunkcje wbudowaneFunkcje zaprzyjaźnione
Spis treści • Semantyka przenoszenia • Składowe statyczne static • Funkcje i metody wbudowaneinline
Semantyka przenoszenia • Konstruktor przenoszący służy do utworzenia nowego obiektu przez przeniesienie danych z obiektu tymczasowego. • Konstruktorem przenoszącym jest konstruktor w klasie Klasa, który można wywołać z jednym argumentem typu:Klasa::Klasa (Klasa &&);Klasa::Klasa (const Klasa &&); • Kopiowanie przenoszące służy do przeniesienia danych z obiektu tymczasowego (najczęściej poprzez wymianę danych z obiektem tymczasowym). • Kopiowanie przenoszące jest przypisaniem w klasie Klasa, który można wywołać z jednym argumentem typu:Klasa & Klasa::operator= (Klasa &&);Klasa & Klasa::operator= (const Klasa &&); • Semantyka przenoszenia jest utożsamiana z wykradaniem danych z obiektu tymczasowego.
Semantyka przenoszenia • Przykład (1): #include <cstring> #include <algorithm> class string { char* data; public: string(const char* p) { size_t size = strlen(p) + 1; data = new char[size]; memcpy(data, p, size); }
Semantyka przenoszenia • Przykład (2): ~string() { delete[] data; } string(const string& that) { size_t size = strlen(that.data) + 1; data = new char[size]; memcpy(data, that.data, size); }
Semantyka przenoszenia • Przykład (3): string(string&& that) { data = that.data; that.data = nullptr; }string& operator=(string that) { std::swap(data, that.data); return *this; }};
Pola statyczne • Każdy obiekt danej klasy ma swój własny zestaw pól z danymi. • Pole statyczne, z deklaratorem static, nie jest częścią obiektu, istnieje poza jakimkolwiek obiektem i jest wspólne dla wszystkich obiektów danej klasy. • Pole statyczne istnieje przez cały czas życia programu, nawet wtedy gdy nie utworzono żadnego obiektu danej klasy.
Pola statyczne • Deklaracja pola statycznego w ciele klasy (w pliku nagłówkowym) nie jest jego definicją. • Przykład klasy z deklaracją pola statycznego:class data{ int dz, mies, rok;public: data (int d, int m, int r) : dz(d), mies(m), rok(r) {/*…*/}static data poczatek_kalendarza;}; • Definicję pola statycznego należy umieścić poza klasą (w pliku źródłowym). • Przykład definicji pola statycznego poza klasą:data data::poczatek_kalendarza(15,10,1582);
Pola statyczne • Odniesienie się do pola statycznego poprzez nazwę klasy:klasa::pole_stat • Do pola statycznego można się też odnieść poprzez jakikolwiek obiekt danej klasy:klasa ob, *wsk;// …ob.pole_statwsk->pole_stat
Statyczne funkcje składowe • Statyczna funkcja składowa, z deklaratorem static, nie odnosi się do żadnego obiektu danej klasy. • Statyczna funkcja składowa może być wywołana w dowolnym momencie, nawet wtedy gdy nie utworzono żadnego obiektu danej klasy. • Deklaracja statycznej funkcji składowej znajduje się w ciele klasy (w pliku nagłówkowym) a jej definicja jest poza klasą (w pliku źródłowym).
Statyczne funkcje składowe • Przykład klasy z deklaracją statycznej funkcji składowej:class data{ int dz, mies, rok;public: data (int d, int m, int r) : dz(d), mies(m), rok(r) {/*…*/}static int roznica (data p, data k);}; • Przykład definicji statycznej funkcji składowej:int data::roznica (data p, data k) {/*…*/} • W ciele statycznej funkcji składowej nie wolno odnosić się do składowych instancyjnych ani do wskaźnika this. • Do statycznej funkcji składowej można odnieść się poprzez nazwę klasy albo poprzez jakikolwiek obiekt danej klasy.
Funkcje wbudowane • Funkcje wbudowane, oznaczone deklaratorem inline, są rozwijane w miejscu wywołania. • Ich definicja musi być znana w momencie kompilacji a nie linkowania, dlatego nie tylko ich deklaracja ale również definicja znajduje się w pliku nagłówkowym. • Deklarator inline to tylko sugestia dla kompilatora aby wbudowywał funkcję w miejscu jej wywołania. • Funkcja inline zostanie skompilowane jako outline w przypadku, gdy: • kompilujemy program do pracy z debuggerem, • funkcja jest rekurencyjna, • pobieramy w programie adres funkcji.
Funkcje wbudowane • Wbudowywanie funkcji w kod ma sens w przypadku krótkich funkcji. • Funkcje wbudowane zwiększają rozmiar programu wynikowego ale przyspieszają jego działanie. • Przykład funkcji wbudowanej:inline int zaokraglenie (double d){ return d<0? int(d-.5): int(d+.5);}
Wbudowane funkcje składowe • W klasie też można definiować wbudowane funkcje składowe. • Metoda zdefiniowana w klasie jest traktowana jako wbudowana. • Metody wbudowane można także definiować poza klasą.
Wbudowane funkcje składowe • Przykład klasy z metodami wbudowanymi:class data{ int dz, mies, r;public: data (int d, int m, int r); int dzien (void) const; int miesiac (void) const { return mies; } inline int rok (void) const { return r; }};inline data::data (int d, int m, int r): dz(d), mies(m), r(r) {}inline int data::dzien (void) const{ return dz; }
Argumenty domyślne • Często mamy taką sytuację, że w ogólnym przypadku funkcja wymaga podania większej liczby argumentów niż w przypadku najprostszym, albo że wartości niektórych argumentów często się powtarzają. • Argumenty funkcji globalnych i funkcji składowych w klasie mogą posiadać argumenty domyślne. • Argumenty domyślne są formą przeciążania nazwy funkcji.
Argumenty domyślne • Argumenty domyślne mogą występować tylko na końcu listy argumentów. • Wartości domyślne nadawane argumentom domyślnym podaje się tylko w deklaracji funkcji, w definicji się tego nie powtarza. • Przy wywoływaniu funkcji z argumentami domyślnymi można pomijać argumenty domyślne od końca. • Wszystkie argumenty mogą być domyślne.
Argumenty domyślne • Przykład funkcji z argumentem domyślnym:// deklaracjavoid drukuj (int x, int podst=10);// definicjavoid drukuj (int x, int podst) {/*…*/}// wywołaniadrukuj(63); // wynik 63drukuj(63,16); // wynik 3Fdrukuj(63,2); // wynik 111111
Nienazwane argumenty • Jeśli argumentu nazwanego nie używa się w ciele funkcji lub funkcji składowej, to kompilator będzie generował ostrzeżenia. • Argumenty, których nie używa się w ciele funkcji mogą nie posiadać swojej nazwy. • Również argumenty domyślne mogą nie posiadać nazwy. • Przykład funkcji z nienazwanym argumentem:void buczenie (int) { /*…*/ }
Funkcja bez argumentów • Jeśli funkcja nie ma żadnych argumentów, to powinno się ją zadeklarować z argumentem void. • Przykład:void buczenie (void);// to jest równoważne z// void buczenie ();// w języku C byłoby to równoważne z // void buczenie (...);