C++

Jak korzystać z szablonów C++

Jak korzystać z szablonów C++

Wprowadzenie

W podstawowym programowaniu C++ typ danych, e.sol., int lub char, należy wskazać w deklaracji lub definicji. Wartość taka jak 4 lub 22 lub -5 to int. Wartość taka jak „A” lub „b” lub „c” to znak. Mechanizm szablonów pozwala programiście na użycie typu ogólnego dla zestawu rzeczywistych typów. Na przykład programista może zdecydować się na użycie identyfikatora T dla int lub char. Algorytm C++ może mieć więcej niż jeden typ ogólny. Powiedzmy, że T dla int lub char, U może oznaczać typ zmiennoprzecinkowy lub wskaźnikowy. Klasa, taka jak ciąg znaków lub klasa wektora, jest jak typ danych, a skonkretyzowane obiekty są jak wartości typu danych, który jest określoną klasą. Tak więc mechanizm szablonów pozwala również programiście na użycie ogólnego identyfikatora typu dla zestawu klas.

Szablon C++ tworzy algorytm niezależny od rodzaju użytych danych. Tak więc ten sam algorytm, z wieloma wystąpieniami tego samego typu, może używać różnych typów w różnych wykonaniach. Jednostki zmiennej, funkcji, struktury i klasy mogą mieć szablony. W tym artykule wyjaśniono, jak deklarować szablony, jak definiować szablony i jak je stosować w C++. Powinieneś już mieć wiedzę na temat wyżej wymienionych podmiotów, aby zrozumieć tematy poruszane w tym artykule.

Rodzaje

Skalarny

Typy skalarne to void, bool, char, int, float i pointer.

Klasy jako typy

Konkretną klasę można uznać za typ, a jej obiekty za możliwe wartości.

Typ ogólny reprezentuje zestaw typów skalarnych. Lista typów skalarnych jest obszerna. Na przykład typ int ma inne powiązane typy, takie jak short int, long int itp. Typ ogólny może również reprezentować zestaw klas.

Zmienna

Przykład deklaracji szablonu i definicji jest następujący:

szablon
Tpi = 3.14;

Zanim przejdziesz dalej, zauważ, że tego rodzaju instrukcja nie może pojawić się w funkcji main() ani w żadnym zakresie bloku. Pierwsza linia to deklaracja nagłówka szablonu, z wybraną przez programistę nazwą typu ogólnego, T. Kolejny wiersz to definicja identyfikatora pi, który jest typu ogólnego T. Precyzję, czy T jest int, float lub jakimś innym typem, można wykonać w funkcji main() C++ (lub innej funkcji). Taka precyzja zostanie zrealizowana ze zmienną pi, a nie T.

Pierwsza linia to deklaracja szablonu-head. Ta deklaracja zaczyna się od słowa zastrzeżonego, szablonu, a następnie nawiasów ostrych otwartych i zamkniętych. W nawiasach kątowych znajduje się co najmniej jeden ogólny identyfikator typu, taki jak T, powyżej. Może istnieć więcej niż jeden identyfikator typu ogólnego, każdy poprzedzony słowem zastrzeżonym typename. Takie ogólne typy w tej pozycji nazywane są parametrami szablonu.

Poniższą instrukcję można zapisać w funkcji main() lub w dowolnej innej funkcji:

Cout << pi << '\n';

A funkcja wyświetli 3.14. Wyrażenie pi decyduje o dokładnym typie T dla zmiennej pi. Specjalizacja decyduje o konkretnym typie danych dla parametru szablonu. Tworzenie instancji to wewnętrzny proces C++ tworzenia konkretnego typu, takiego jak w tym przypadku float. Nie myl między tworzeniem instancji parametru szablonu a tworzeniem instancji klasy. W temacie dotyczącym szablonu wiele typów danych może mieć jedną ogólną nazwę typu, podczas gdy wiele klas może mieć jedną ogólną nazwę klasy. Jednak ogólna nazwa klasy jest po prostu określana jako klasa, a nie jako nazwa klasy. Ponadto wartość odnosi się do typu danych, takiego jak int, tak jak skonkretyzowany obiekt do klasy, takiej jak klasa String.

W przypadku specjalizacji wybrany typ danych, np. float, umieszczany jest w nawiasach ostrych po zmiennej. Jeśli w deklaracji template-head występuje więcej niż jeden parametr szablonu, w wyrażeniu specjalizacji będzie odpowiednia liczba typów danych w tej samej kolejności.

W specjalizacji typ jest znany jako argument szablonu. Nie myl tego z argumentem funkcji dla wywołania funkcji.

Domyślny typ

Jeśli przy specjalizacji nie podano typu, przyjmuje się typ domyślny. Tak więc z następującego wyrażenia:

szablon
U pi = "miłość";
wyświetlacz z:
Cout << pi<> << '\n';

to „miłość” dla stałego wskaźnika do char. Zauważ w deklaracji, że U = const char*. W przypadku specjalizacji nawiasy kątowe będą puste (nie podano typu); rzeczywisty typ jest uważany za stały wskaźnik do char, typ domyślny. Gdyby do specjalizacji potrzebny był inny typ, to nazwa typu byłaby wpisywana w nawiasach ostrych. Gdy typ domyślny jest wymagany przy specjalizacji, powtórzenie typu w nawiasach ostrych jest opcjonalne, i.mi., nawiasy kątowe można pozostawić puste.

Uwaga: domyślny typ można nadal zmienić podczas specjalizacji, mając inny typ.

struktura

Poniższy przykład pokazuje, jak parametr szablonu może być używany ze strukturą:

szablon struktura Wieki

T Jan = 11;
T Piotr = 12;
T Mary = 13;
T Radość = 14;
;

To są wieki uczniów w klasie (klasie). Pierwsza linia to deklaracja szablonu. Ciało w nawiasach klamrowych jest faktyczną definicją szablonu. Wiek można wyprowadzić w funkcji main() w następujący sposób:

Wieczność 7 klasa;
Cout << grade7.John << " << grade7.Mary << '\n';

Wyjście to: 11 13. Pierwsza instrukcja tutaj wykonuje specjalizację. Zwróć uwagę, jak to zostało zrobione. Daje również nazwę dla obiektu struktury: grade7. Druga instrukcja zawiera zwykłe wyrażenia obiektów struct. Struktura jest jak klasa. Tutaj Ages jest jak nazwa klasy, podczas gdy grade7 jest obiektem klasy (struct).

Jeśli niektóre przedziały wiekowe są liczbami całkowitymi, a inne zmiennoprzecinkowe, wówczas struktura potrzebuje dwóch parametrów ogólnych, takich jak:

szablon struktura Wieki

T Jan = 11;
U Piotra = 12.3;
T Mary = 13;
Radość = 14.6;
;

Odpowiedni kod funkcji main() wygląda następująco:

Wieczność 7 klasa;
Cout << grade7.John << " << grade7.Peter << '\n';

Wyjście to: 11 12.3. Przy specjalizacji kolejność typów (argumentów) musi odpowiadać kolejności typów generycznych w deklaracji.

Deklarację szablonu można oddzielić od definicji w następujący sposób:

szablon struktura Wieki

Jan;
U Piotra;
T Maryja;
U Radość;
;
Wieczność ocena 7 = 11, 12.3, 13, 14.6;

Pierwszy segment kodu to czysta deklaracja szablonu (nie ma przypisań). Drugi segment kodu, który jest tylko stwierdzeniem, to definicja identyfikatora grade7. Po lewej stronie znajduje się deklaracja identyfikatora, grade7. Po prawej stronie znajduje się lista inicjująca, która przypisuje odpowiednie wartości do członków struktury. Drugi segment (instrukcję) można zapisać w funkcji main(), podczas gdy pierwszy segment pozostaje poza funkcją main().

Nietypowe

Przykłady typów innych niż dane obejmują int, wskaźnik do obiektu, wskaźnik do funkcji i typy auto. Istnieją inne nietypy, których ten artykuł nie dotyczy. Nietyp jest jak niekompletny typ, którego wartość jest podana później i nie można jej zmienić. Jako parametr zaczyna się od określonego nietypu, po którym następuje identyfikator. Wartość identyfikatora jest podawana później, przy specjalizacji i nie może być ponownie zmieniona (jak stała, której wartość jest podana później). Poniższy program ilustruje to:

#zawierać
przy użyciu standardowej przestrzeni nazw;
szablon struktura Wieki

T Jan = N;
U Piotra = 12.3;
T Mary = N;
Radość = 14.6;
;
int main()

Wieczność 7 klasa;
Cout << grade7.John << " << grade7.Joy << '\n';
zwróć 0;

Na specjalizacji pierwszy typ, int, w nawiasach ostrych jest bardziej formalny, aby upewnić się, że liczba i kolejność parametrów odpowiada liczbie i kolejności typów (argumentów). Wartość N została podana na specjalizacji. Wyjście to: 11 14.6.

Częściowa specjalizacja

Załóżmy, że szablon ma cztery typy ogólne i że wśród czterech typów potrzebne są dwa typy domyślne. Można to osiągnąć za pomocą konstrukcji częściowej specjalizacji, która nie wykorzystuje operatora przypisania. Tak więc konstrukcja częściowej specjalizacji daje wartości domyślne podzbiorowi typów ogólnych. Jednak w schemacie częściowej specjalizacji potrzebna jest klasa bazowa (struct) i klasa częściowej specjalizacji (struct). Poniższy program ilustruje to dla jednego typu ogólnego z dwóch typów ogólnych:

#zawierać
przy użyciu standardowej przestrzeni nazw;
//podstawowa klasa szablonu
szablon
struktura Wieki

;
//częściowa specjalizacja
szablon
struktura Wieki

T1 Jan = 11;
pływak Piotr = 12.3;
T1 Maria = 13;
pływak Radość = 14.6;
;
int main()

Wieczność 7 klasa;
Cout << grade7.John << " << grade7.Joy << '\n';
zwróć 0;

Zidentyfikuj deklarację klasy bazowej i jej częściową definicję klasy. Deklaracja nagłówka szablonu klasy bazowej zawiera wszystkie niezbędne parametry ogólne. Deklaracja szablonu-head klasy częściowej specjalizacji ma tylko typ ogólny type. W schemacie zastosowano dodatkowy zestaw nawiasów ostrych, który znajduje się zaraz po nazwie klasy w definicji częściowej specjalizacji. To właśnie robi częściowa specjalizacja. Ma typ domyślny i typ inny niż domyślny, w kolejności zapisanej w klasie bazowej. Zauważ, że domyślny typ nadal może mieć inny typ w funkcji main().

Odpowiedni kod w funkcji main() może wyglądać następująco:

Wieczność 7 klasa;
Cout << grade7.John << " << grade7.Joy << '\n';

Wyjście to: 11 14.6.

Pakiet parametrów szablonu

Pakiet parametrów to parametr szablonu, który akceptuje zero lub więcej typów ogólnych szablonów dla odpowiednich typów danych. Parametr pakietu parametrów zaczyna się od zastrzeżonego słowa typename lub class. Po nim następują trzy kropki, a następnie identyfikator paczki. Poniższy program ilustruje, w jaki sposób pakiet parametrów szablonu może być używany ze strukturą:

#zawierać
przy użyciu standardowej przestrzeni nazw;
szablon struktura Wieki

int Jan = 11;
pływak Piotr = 12.3;
int Maria = 13;
pływak Radość = 14.6;
;
int main()

Wieczność klasa B;
Cout << gradeB.John << " << gradeB.Mary << '\n';
Wieczność stopień C;
Cout << gradeC.Peter << " << gradeC.Joy << '\n';
Wieczność stopień D;
Cout << gradeD.John << " << gradeD.Joy << '\n';
Wiek<> klasa A; //jak domyślne
Cout << gradeA.John << " << gradeA.Joy << '\n';
zwróć 0;

Dane wyjściowe to:

11 13
12.3 14.6
11 14.6
11 14.6

Szablony funkcji

Wspomniane wyżej cechy szablonów mają zastosowanie w podobny sposób do szablonów funkcji. Poniższy program pokazuje funkcję z dwoma ogólnymi parametrami szablonu i trzema argumentami:

#zawierać
przy użyciu standardowej przestrzeni nazw;
szablon void func (T no, U cha, const char *str )

Cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main()

func(12, '$', "500");
zwróć 0;

Dane wyjściowe są następujące:

W sklepie jest 12 książek o wartości 500$.

Oddzielenie od prototypu

Definicję funkcji można oddzielić od jej prototypu, jak pokazuje poniższy program:

#zawierać
przy użyciu standardowej przestrzeni nazw;
szablon void func (T no, U cha, const char *str );
szablon void func (T no, U cha, const char *str )

Cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

int main()

func(12, '$', "500");
zwróć 0;

Uwaga: Deklaracja szablonu funkcji nie może pojawić się w funkcji main() ani w żadnej innej funkcji.

Przeciążenie

Przeciążanie tej samej funkcji może mieć miejsce przy różnych deklaracjach szablonów-nagłówków. Poniższy program ilustruje to:

#zawierać
przy użyciu standardowej przestrzeni nazw;
szablon void func (T no, U cha, const char *str )

Cout << "There are " << no << " books worth " << cha << str << " in the store." << '\n';

szablon void func (T no, const char *str )

Cout << "There are " << no << " books worth $" << str << " in the store." << '\n';

int main()

func(12, '$', "500");
func(12, "500");
zwróć 0;

Dane wyjściowe to:

W sklepie jest 12 książek o wartości 500$.

W sklepie jest 12 książek o wartości 500$.

Szablony zajęć

Wspomniane wyżej cechy szablonów mają zastosowanie w podobny sposób do szablonów klasowych. Poniższy program jest deklaracją, definicją i użyciem prostej klasy:

#zawierać
przy użyciu standardowej przestrzeni nazw;
klasa TheCla

publiczny:
liczba wewnętrzna;
znak statyczny;
void func (char cha, const char *str)

Cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

static void fun (char ch)

jeśli (ch == 'a')
Cout << "Official static member function" << '\n';

;
int main()

Objekt Claa;
obiekt.liczba = 12;
obiekt.func('$', "500");
zwróć 0;

Dane wyjściowe są następujące:

W sklepie jest 12 książek o wartości 500$.

Poniższy program jest powyższym programem z deklaracją szablonu-nagłówka:

#zawierać
przy użyciu standardowej przestrzeni nazw;
szablon klasa TheCla

publiczny:
liczba T;
statyczny Uch;
void func (U cha, const char *str)

Cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

pustka statyczna zabawa (U ch)

jeśli (ch == 'a')
Cout << "Official static member function" << '\n';

;
int main()

TheCla przedmiot;
obiekt.liczba = 12;
obiekt.func('$', "500");
zwróć 0;

Zamiast nazwy typu słowa na liście parametrów szablonu można użyć klasy słowa. Zwróć uwagę na specjalizację w deklaracji obiektu. Dane wyjściowe są nadal takie same:

W sklepie jest 12 książek o wartości 500$.

Deklaracja separacji

Deklarację szablonu klasy można oddzielić od kodu klasy w następujący sposób:

szablon klasa TheCla;
szablon klasa TheCla

publiczny:
liczba T;
statyczny Uch;
void func (U cha, const char *str)

Cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

pustka statyczna zabawa (U ch)

jeśli (ch == 'a')
Cout << "Official static member function" << '\n';

;

Postępowanie z członkami statycznymi

Poniższy program pokazuje, jak uzyskać dostęp do statycznej składowej danych i statycznej funkcji składowej:

#zawierać
przy użyciu standardowej przestrzeni nazw;
szablon klasa TheCla

publiczny:
liczba T;
statyczny Uch;
void func (U cha, const char *str)

Cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

pustka statyczna zabawa (U cha)

jeśli (ch == 'a')
Cout << "Official static member function" << cha << '\n';

;
szablon U TheCla::ch = 'a';
int main()

TheCla::zabawa('.');
zwróć 0;

Przypisanie wartości do statycznego elementu danych jest deklaracją i nie może znajdować się w main(). Zwróć uwagę na użycie i pozycje typów ogólnych oraz typu ogólnego danych w instrukcji przypisania. Ponadto należy zauważyć, że funkcja składowa danych statycznych została wywołana w funkcji main() z rzeczywistymi typami danych szablonu template. Dane wyjściowe są następujące:

Oficjalna funkcja statycznego członka.

Kompilacja

Deklaracja (nagłówek) i definicja szablonu muszą znajdować się w jednym pliku. Oznacza to, że muszą znajdować się w tej samej jednostce tłumaczeniowej.

Wniosek

Szablony C++ tworzą algorytm niezależny od rodzaju użytych danych. Jednostki zmiennej, funkcji, struktury i klasy mogą mieć szablony, które obejmują deklarację i definicję. Tworzenie szablonu wiąże się również ze specjalizacją, czyli wtedy, gdy typ ogólny przyjmuje typ rzeczywisty. Oświadczenie i definicja szablonu muszą znajdować się w jednej jednostce tłumaczeniowej.

Microsoft Sculpt Touch Wireless Mouse Review
I recently read about the Microsoft Sculpt Touch wireless mouse and decided to buy it. After using it for a while, I decided to share my experience wi...
AppyMouse On-screen Trackpad and Mouse Pointer for Windows Tablets
Tablet users often miss the mouse pointer, especially when they are habitual to using the laptops. The touchscreen Smartphones and tablets come with m...
Middle mouse button not working in Windows 10
The middle mouse button helps you scroll through long webpages and screens with a lot of data. If that stops, well you will end up using the keyboard ...