Szybki przegląd
Złożone typy danych (tzw dane złożone type) to typy danych, które można skonstruować z podstawowych typów danych (lub innych złożonych typów danych).
Klasa kategoria wartości wyrażenia wskazuje, czy wyrażenie prowadzi do wartości, funkcji, czy jakiegoś rodzaju obiektu.
An wartość to wyrażenie, którego wynikiem jest funkcja lub obiekt mający tożsamość. Obiekt lub funkcja posiadająca tożsamość posiada identyfikator lub możliwy do zidentyfikowania adres pamięci. Lwartości dzielą się na dwa podtypy: modyfikowalne lwartości to lwartości, które można modyfikować oraz niemodyfikowalne lwartości to lwartości, których wartości nie można modyfikować (zwykle ponieważ są to const lub constexpr).
An wartość to wyrażenie, które jest nie wartość l. Obejmuje to literały (z wyjątkiem literałów łańcuchowych) i wartości zwracane przez funkcje lub operatory (jeśli są zwracane przez wartość).
A odniesieniem jest aliasem istniejącego obiektu. Po zdefiniowaniu odniesienia, wszelkie operacje na nim zostaną zastosowane do obiektu, do którego się odwołujemy. C++ zawiera dwa typy odniesień: odniesienia do wartości i odniesienia do wartości. Odniesienie do wartości (zwykle nazywane po prostu odniesieniem odniesieniem) działa jako alias dla istniejącej wartości (takiej jak zmienna). Zmienna referencyjna wartości jest zmienną, która działa jako odniesienie do lwartości (zwykle innej zmiennej).
Gdy odwołanie jest inicjowane obiektem (lub funkcją), mówimy, że jest powiązane z tym obiektem (lub funkcją). Obiekt (lub funkcja), do którego się odwołujemy, jest czasami nazywany referentem.
Odniesienia do wartości nie mogą być powiązane z niemodyfikowalnymi l-wartościami lub rwartościami (w przeciwnym razie można by zmienić te wartości poprzez odniesienie, co byłoby naruszeniem ich stałości). Z tego powodu odniesienia do lwartości są czasami nazywane odniesieniami wartości do wartości niestałych (czasami skracane do odniesieniami niestałymi).
Po zainicjowaniu odwołanie w C++ nie może być ponownie umieszczone, co oznacza, że nie można ich zmienić tak, aby odwoływały się do innego obiektu.
Gdy obiekt, do którego odnosi się odwołanie, zostaje zniszczony przed powołaniem się do niego, odniesienie pozostaje odniesieniem do obiektu, który już nie istnieje. Takie odniesienie nazywa się odniesieniem wiszącym. Dostęp do odniesienia wiszącego prowadzi do niezdefiniowanego zachowania.
Używając słowa kluczowego const podczas deklarowania odniesienia do wartości, informujemy Odniesienie do wartości, aby traktować obiekt, do którego się odwołuje, jako do stałej. Takie odniesienie nazywa się odniesieniem do wartości stałej (czasami nazywany odniesieniem do const lub a odniesieniem do stałej rwartości.
A obiekt tymczasowy (czasami nazywany obiektem bez nazwy lub obiektem anonimowym) to obiekt, który jest tworzony do tymczasowego użytku (a następnie niszczony) w ramach jednego wyrażenia.
Podczas używania przejdź obok referencja, deklarujemy parametr funkcji jako referencję (lub stałą referencję), a nie jako zwykłą zmienną. Kiedy funkcja jest wywoływana, każdy parametr referencyjny jest powiązany z odpowiednim argumentem, ponieważ referencja działa jak alias argumentu, nie jest tworzona żadna kopia argumentu.
Klasa adres operatora (&) zwraca adres pamięci swojego operandu. Operator wyłuskiwania (*) zwraca wartość pod danym adresem pamięci jako lwartość.
A wskaźnik jest obiektem, który przechowuje adres pamięci (zazwyczaj innej zmiennej) jako swoją wartość. Dzięki temu możemy zapisać adres innego obiektu do późniejszego wykorzystania. Podobnie jak zwykłe zmienne, wskaźniki nie są domyślnie inicjowane. Wskaźnik, który nie został zainicjowany, nazywany jest czasem wskaźnikiem dzikim. A wskaźnikiem wiszącym to wskaźnik przechowujący adres obiektu, który nie jest już ważny (np. ponieważ został zniszczony).
Oprócz adresu pamięci, istnieje jeszcze jedna dodatkowa wartość, którą wskaźnik może przechowywać: wartość null. A wartość null (często skracana do null) to wartość specjalna, która oznacza, że coś nie ma wartości. Gdy wskaźnik przechowuje wartość null, oznacza to, że wskaźnik na nic nie wskazuje. Taki wskaźnik nazywany jest wskaźnikiem zerowym. Słowo kluczowe nullptr reprezentuje literał wskaźnika zerowego. Możemy użyć nullptr do jawnej inicjalizacji lub przypisania wskaźnikowi wartości null.
Wskaźnik powinien albo zawierać adres prawidłowego obiektu, albo być ustawiony na nullptr. W ten sposób musimy jedynie przetestować wskaźniki pod kątem wartości null i możemy założyć, że dowolny wskaźnik inny niż null jest prawidłowy.
A wskaźnik do wartości stałej (czasami nazywany wskaźnikiem do const w skrócie) jest (niestałym) wskaźnikiem, który wskazuje na wartość stałą.
A const wskaźnik jest wskaźnikiem, którego adresu nie można zmienić po inicjalizacji.
A const wskaźnik do wartości stałej nie może zmienić swojego adresu ani wartości, którą wskazuje, można zmienić za pomocą wskaźnika.
Przy przekazaniu adresu zamiast podawania obiektu jako argumentu, wywołujący podaje adres obiektu (poprzez wskaźnik). Wskaźnik ten (zawierający adres obiektu) jest kopiowany do parametru wskaźnika wywoływanej funkcji (która teraz przechowuje także adres obiektu). Funkcja może następnie wyłuskać ten wskaźnik, aby uzyskać dostęp do obiektu, którego adres został przekazany.
Return by reference zwraca referencję powiązaną ze zwracanym obiektem, co pozwala uniknąć tworzenia kopii zwracanej wartości. Użycie funkcji return przez referencję ma jedno główne zastrzeżenie: programista musi mieć pewność, że obiekt, do którego się odwołuje, przetrwa funkcję zwracającą referencję. W przeciwnym razie zwracane odniesienie pozostanie zawieszone (odnoszące się do obiektu, który został zniszczony), a użycie tego odniesienia spowoduje niezdefiniowane zachowanie. Jeśli parametr jest przekazywany do funkcji przez referencję, można bezpiecznie zwrócić ten parametr przez referencję.
Jeśli funkcja zwróci referencję, a referencja ta zostanie użyta do inicjalizacji lub przypisania zmiennej niebędącej referencją, zwrócona wartość zostanie skopiowana (tak jakby została zwrócona przez wartość).
Wpisz dedukcję dla zmiennych (za pomocą auto słowa kluczowego) usunie wszelkie referencje lub stałe najwyższego poziomu kwalifikatory z wydedukowanego typu. W razie potrzeby można je ponownie zastosować jako część deklaracji zmiennej.
Zwrot przez adres działa prawie identycznie jak powrót przez referencję, z tą różnicą, że zamiast referencji do obiektu zwracany jest wskaźnik do obiektu.
Czas quizu
Pytanie nr 1
Dla każdego z poniższych wyrażeń po prawej stronie operatora << wskaż, czy wyrażenie jest wartością czy wartością:
A)
std::cout << 5;B)
int x { 5 };
std::cout << x;C)
int x { 5 };
std::cout << x + 1;D)
int foo() { return 5; }
std::cout << foo();mi)
int& max(int &x, int &y) { return x > y ? x : y; }
int x { 5 };
int y { 6 };
std::cout << max(x, y);Pytanie nr 2
Jaki jest wynik tego programu?
#include <iostream>
int main()
{
int x{ 4 };
int y{ 6 };
int& ref{ x };
++ref;
ref = y;
++ref;
std::cout << x << ' ' << y;
return 0;
}Pytanie nr 3
Wymień dwa powody, dla których wolimy przekazywać argumenty poprzez odwołanie do stałej zamiast przez odniesienie inne niż stałe, jeśli to możliwe.
Pytanie nr 4
Jaka jest różnica pomiędzy wskaźnikiem const a wskaźnikiem do stałej?
Pytanie #5
Napisz funkcję o nazwie sort2 która pozwala wywołującemu przekazać 2 zmienne typu int jako argumenty. Gdy funkcja powraca, pierwszy argument powinien zawierać mniejszą z dwóch wartości, a drugi argument powinien zawierać większą z dwóch wartości.
Wskazówka: Funkcja std::swap() (w nagłówku <algorithm>) może zostać użyta do zamiany wartości dwóch zmiennych. np. std::swap(x, y) zamienia wartości zmiennych x i y.
Następujący kod powinien zostać uruchomiony i wydrukować wartości zapisane w komentarzach:
#include <iostream>
int main()
{
int x { 7 };
int y { 5 };
std::cout << x << ' ' << y << '\n'; // should print 7 5
sort2(x, y); // make sure sort works when values need to be swapped
std::cout << x << ' ' << y << '\n'; // should print 5 7
sort2(x, y); // make sure sort works when values don't need to be swapped
std::cout << x << ' ' << y << '\n'; // should print 5 7
return 0;
}
