Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałAgnieszka Jastrzębska Został zmieniony 8 lat temu
1
K URS JĘZYKA C++ – WYKŁAD 3 (11.03.2015) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne
2
S PIS TREŚCI Argumenty tymczasowe Semantyka przenoszenia Inicjalizacja za pomocą list Składowe statyczne static Funkcje i metody wbudowane inline Argumenty domyślne
3
A RGUMENTY TYMCZASOWE Obiekty tymczasowe (określane jako r-wartości), to wartości stojące po prawej stronie operatora przypisania (analogicznie zwykła referencja do zmiennej stojącej po lewej stronie przypisania nazywa się l-wartością). Obiekty tymczasowe (określane jako r-wartości), mogą być przekazywane do funkcji jako referencje do stałych. Z punktu widzenia funkcji, której argumentem jest referencja do stałej, nie jest możliwe rozróżnienie pomiędzy aktualną r- wartością a zwykłym obiektem przekazanym przez referencję.
4
A RGUMENTY TYMCZASOWE Argument w funkcji będący referencją do r-wartości definiujemy jako TYP &&arg. Argument będący r-referencją może być akceptowany jako niestała wartość, co pozwala funkcjom na ich modyfikację. Z punktu widzenia funkcji, której argumentem jest referencja do stałej, nie jest możliwe rozróżnienie pomiędzy aktualną r- wartością a zwykłym obiektem przekazanym referencję. Argumenty r-referencyjne umożliwiają pewnym obiektom na stworzenie semantyki przenoszenia za pomocą konstruktorów przenoszących oraz przypisań przenoszących.
5
S EMANTYKA 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.
6
S EMANTYKA PRZENOSZENIA Przykład (1): #include #include class string { char* data; public: string(const char* p) { size_t size = strlen(p) + 1; data = new char[size]; memcpy(data, p, size); } ~string() { delete[] data; }
7
S EMANTYKA PRZENOSZENIA Przykład (2): string(const string &that) { size_t size = strlen(that.data) + 1; data = new char[size]; memcpy(data, that.data, size); } string (string &&that) { data = that.data; that.data = nullptr; }
8
S EMANTYKA PRZENOSZENIA Przykład (3): string& operator= (const string &that) { if (this == &that) return *this; this->~string(); size_t size = strlen(that.data) + 1; data = new char[size]; memcpy(data, that.data, size); return *this; } string& operator= (string &&that) { std::swap(data, that.data); return *this; } };
9
I NICJALIZACJA ZA POMOCĄ LIST Inicjowanie list jest w C++ zapożyczone z języka C. Ideą jest, by struktura lub tablica były tworzone przez podanie listy argumentów o kolejności zgodnej, odpowiednio, z kolejnością definicji składowych struktury lub kolejnymi elementami tablicy. Listy inicjalizujące są rekursywne i mogą być zastosowane także do tablicy struktur albo struktury zawierającej inne struktury. W C++ można definiować konstruktory, które naśladują takie inicjalizowanie obiektu za pomocą listy wartości. C++ wiąże koncepcję inicjalizowania list z typem std::initializer_list<>.
10
I NICJALIZACJA ZA POMOCĄ LIST Konstruktor inicjalizujący za pomocą listy, zwany też konstruktorem sekwencji, definiujemy w klasie Klasa z jednym argumentem typu initializer_list<> : Klasa::Klasa (initializer_list ); To pozwala obiektowi typu Klasa być skonstruowanym z sekwencji wartości typu T przy użyciu składni z klamrami. Przykład: class JakasKlasa { public: JakasKlasa(std::initializer_list list); //… }; //… JakasKlasa ob1 = {2, 3, 5, 7}; JakaKlasa ob2{11, 13, 17, 19};
11
J EDNOLITA INICJALIZACJA …
13
P OLA 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.
14
P OLA 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);
15
P OLA 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_stat wsk->pole_stat
16
S TATYCZNE 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).
17
S TATYCZNE 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. Statyczna funkcja składowa nie może się bezpśrednio odwoływać do składowych instancyjnych.
18
F UNKCJE 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.
19
F UNKCJE WBUDOWANE Wbudowywanie funkcji w kod ma sens w przypadku krótkich funkcji, które są często wywoływane. 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); }
20
W BUDOWANE 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ą (aby funkcja wbudowana była wstawiana w miejsce wywołania, to jej definicja powinna się znaleźć w pliku nagłówkowym).
21
W BUDOWANE 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; }
22
A RGUMENTY 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.
23
A RGUMENTY 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.
24
A RGUMENTY DOMYŚLNE Przykład funkcji z argumentem domyślnym: // deklaracja void drukuj (int x, int podst=10); // definicja void drukuj (int x, int podst) {/*…*/} // wywołania drukuj(63); // wynik 63 drukuj(63,16); // wynik 3F drukuj(63,2); // wynik 111111
25
N IENAZWANE 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) { /*…*/ }
26
F UNKCJA 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 (...);
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.