System typów C++ (Podręcznik programowania C++ nowoczesny)
Pojęcie typu bardzo ważną rolę w języku C++.Każdy zmiennych, argument funkcji oraz funkcji zwracać wartość musi mieć typ celu skompilowania.Ponadto każdy wyrażenie (w tym wartości literału) niejawnie podano typ przez kompilator przed obliczeniem go.Niektóre przykłady to int do przechowywania wartości integralną, double do przechowywania wartości zmiennoprzecinkowe (znany również jako skalarnych typów danych), lub klasy standardowa biblioteka std::basic_string do przechowywania tekstu.Można także utworzyć własny typ definiując class lub struct.Typ określa ilość pamięci, która zostanie zaalokowana do zmiennej (lub wynik wyrażenia), rodzaje wartości, które mogą być przechowywane w tej zmiennej, interpretowania tych wartości (jako wzorca bitów) i operacje, które można wykonywać na nim.W tym artykule omówiono nieformalne najważniejszych funkcji system typów C++.
Terminologia
Zmiennej: symboliczny nazwa ilości danych, tak aby nazwy umożliwia dostęp do danych odnosi się do całej zakres kodu, w którym jest zdefiniowana.W języku C++ "Zmienna" jest zazwyczaj używany do odnoszą się do wystąpienia typów danych skalarnych, natomiast wystąpienia typów, inne są zwykle nazywane "obiektów".
Obiekt: dla uproszczenia i zachowania spójności, w tym artykule posługuje się terminem "obiekt" do odwoływania się do wystąpienia klasy lub struktury, a kiedy jest używany w ogólnym sensie obejmuje wszystkie typy, nawet zmienne skalarne.
Typ POD (zwykły stare dane): tej kategorii nieformalne typów danych języka c++ odnosi się do typów, które są skalarną (patrz sekcja podstawowych typów) lub są klas POD.Klasa POD nie ma żadnych członków dane statyczne, które nie są również strąków i nie ma zdefiniowanej przez użytkownika konstruktory, destruktory zdefiniowane przez użytkownika lub operatory przypisania użytkownika.Ponadto klasa POD ma nie funkcje wirtualnego, żadna klasa podstawowa i żadnych członków prywatnym ani chronionym Niestatyczne pola.Typy POD są często używane do wymiany danych zewnętrznych, na przykład przy użyciu modułu napisana w języku C (która ma tylko typy TSD).
Określanie typów zmiennych oraz funkcji
C++ jest jednoznacznie określony typ języka i jest również - statycznymi; Każdy obiekt ma typ i nigdy nie wpisz zmian (nie należy mylić z obiektami danych statycznych).
Kiedy zadeklarujemy zmienną w kodzie, musisz jawnie określić jego typ, lub użyć auto słowo kluczowe, aby nakazać kompilatorowi wywnioskowanie typu z inicjatora.
Kiedy deklarowania funkcji w kodzie, należy określić typ każdego argumentu i wartości zwracanej, lub void Jeśli wartość nie jest zwracana przez funkcję.Wyjątkiem jest, gdy używana jest funkcja szablony, które pozwalają na argumenty dowolnych typów.
Po pierwsze zadeklarujemy zmienną, nie można zmienić jego typ, w pewnym momencie później.Jednakże wartość zmiennej lub wartość zwracana przez funkcję można skopiować do innej zmiennej innego typu.Takie operacje są nazywane konwersje typów, które są czasem niezbędne, ale również są potencjalnymi źródłami danych straty lub nieprawidłowości.
Przy deklarowaniu zmiennej typu POD zalecamy należy go zainicjować, co oznacza, aby nadać mu wartość początkową.Dopóki nie można zainicjować zmienną, ma wartość "śmieci", która składa się niezależnie od usługi bits stało się wcześniej w tej lokalizacji pamięci.Jest to ważny aspekt C++ do zapamiętania, zwłaszcza, jeśli pochodzą z innego języka, który obsługuje inicjowania dla Ciebie.Przy deklarowaniu zmiennej typu non-POD klasy, konstruktor obsługuje inicjowania.
W poniższym przykładzie przedstawiono kilka prostych deklaracji zmiennych z niektóre opisy dla każdego.W przykładzie pokazano również, jak kompilator używa informacji o typie aby umożliwiać lub uniemożliwiać niektórych kolejnych operacji w zmiennej.
int result = 0; // Declare and initialize an integer.
double coefficient = 10.8; // Declare and initialize a floating
// point value.
auto name = "Lady G."; // Declare a variable and let compiler
// deduce the type.
auto address; // error. Compiler cannot deduce a type
// without an intializing value.
age = 12; // error. Variable declaration must
// specify a type or use auto!
result = "Kenny G."; // error. Can’t assign text to an int.
string result = "zero"; // error. Can’t redefine a variable with
// new type.
int maxValue; // Not recommended! maxValue contains
// garbage bits until it is initialized.
Podstawowe typy (wbudowane)
Inaczej niż w przypadku niektórych języków C++ nie ma uniwersalnej podstawowego typu od których pochodzą wszystkich innych typów.Visual C++ Implementacja języka obejmuje wiele podstawowych typów, znany również jako wbudowanych typów.Obejmuje to typy liczbowe takich jak int, double, long, bool, plus char i wchar_t odpowiednio typy znaków ASCII i UNICODE.Najbardziej podstawowych typów (z wyjątkiem bool, double, wchar_t i pokrewne typy) mają wszystkie niepodpisane wersje, które zmieniają zakres wartości, które mogą być przechowywane w zmiennej.Na przykład int, który przechowuje 32-bitową całkowitą podpisane może reprezentować wartość od 648 do 2 147 483 647.unsigned int, Który także jest przechowywany jako 32 bity można przechowywać wartości od 0 do 4 294 967 295.Całkowita liczba możliwych wartości w każdym przypadku jest taka sama; różni się tylko zakres.
Podstawowe typy są rozpoznawane przez kompilator, który posiada wbudowane reguły, które kontrolują jakie operacje można wykonywać na nich, jak mogą być konwertowane na inne typy podstawowe.Aby uzyskać pełną listę wbudowanych typów i ich wielkości i liczbowe limitów, zobacz Podstawowe typy (C++).
Na poniższej ilustracji przedstawiono względnych wielkości wbudowanych typów:
Następująca tabela zawiera listę często używanych typów podstawowych:
Typ |
Rozmiar |
Komentarz |
---|---|---|
int |
4 bajty |
Domyślnie jest wybrana integralną wartości. |
double |
8 bajtów |
Domyślnie jest wybrana wartości zmiennoprzecinkowe. |
bool |
1 bajt |
Reprezentuje wartości, które mogą mieć wartość PRAWDA lub FAŁSZ. |
char |
1 bajt |
Służy do znaków ASCII w starszych ciągi stylu języka C lub obiektów szablonowej, które nigdy nie będą musiały być konwertowane na standard UNICODE. |
wchar_t |
2 bajty |
Reprezentuje znak "szerszej" wartości, które mogą być zakodowane w formacie UNICODE (UTF-16, w systemie Windows, inne systemy operacyjne mogą się różnić).Jest to typ znaku, który jest używany w ciągach znaków typu std::wstring. |
niepodpisany char |
1 bajt |
C++ zawiera wbudowane nie byte typu.Bez znaku (znak) służy do przedstawiania wartość bajtu. |
niepodpisany int |
4 bajty |
Domyślnym wyborem dla flag bitowych. |
długi |
8 bajtów |
Reprezentuje bardzo dużej liczby całkowite. |
Typ void
void Typu jest specjalnym typem; Nie można zadeklarować zmiennej typu void, ale można zadeklarować zmiennej typu void * (wskaźnik, aby void), który czasami konieczne jest przy przydzielaniu pamięci (programu).Jednakże wskaźniki do void są nie typ palety i ogólnie ich wykorzystania jest zdecydowanie odradzane nowoczesnego języka c++.W deklaracji funkcji void zwraca wartość oznacza, że funkcja nie zwraca wartości; jest to wykorzystanie wspólnych i dopuszczalne z void.Podczas gdy funkcje wymagane języka C, które mają zero parametrów, aby zadeklarować void na liście parametrów, na przykład, fou(void), praktyka ta jest odradzane nowoczesnego języka c++ i powinien być zadeklarowany jako fou().Aby uzyskać więcej informacji, zobacz Typ konwersji i typ bezpieczeństwa (C++).
kwalifikator typu const
Dowolny typ wbudowanej lub zdefiniowanej przez użytkownika mogą być nazwami kwalifikowanymi według słowa kluczowego const.Ponadto funkcje składowe może być const-kwalifikowaną, a nawet const-nadmiernie obciążony.Wartość const typu nie można zmieniać po jego inicjowania.
const double PI = 3.1415;
PI = .75 //Error. Cannot modify const variable.
const Kwalifikator jest szeroko stosowane w deklaracji funkcji i zmiennych i "const poprawność" jest bardzo ważnym pojęciem w języku C++; Zasadniczo oznacza to wykorzystanie const w celu zagwarantowania, w czasie kompilacji, że wartości nie zmodyfikować niechcący.Aby uzyskać więcej informacji, zobacz Const (C++).
A const typu różni się od wersji nie const; na przykład const int jest typ samodzielny z int.Można użyć C++ const_cast operatora w tych rzadkich przypadkach, kiedy należy usunąć ności const ze zmienną.Aby uzyskać więcej informacji, zobacz Typ konwersji i typ bezpieczeństwa (C++).
Ciąg typów
Trzeba dodać języka C++ nie ma wbudowanego "ciąg" typu; chari wchar_t przechowywania pojedynczych znaków-należy zadeklarować tablicę tych typów zbliżenie ciąg, dodawanie zakończeń wartość null (na przykład ASCII ‘\0’) do jednego elementu tablicy za ostatnim elementem prawidłowy (zwane również "ciąg stylu C").Ciągi stylu C wymagane znacznie więcej kodu do napisania lub korzystanie z funkcji biblioteki, narzędzie zewnętrzne ciąg.Ale nowoczesnego języka c++, mamy typów standardowa biblioteka std::string (dla 8-bitowa char-wpisz ciągów znaków) lub std::wstring (dla 16-bitowych wchar_t-wpisz ciągów znaków).Takie pojemniki STL można traktować jako ciąg rodzimych typów ponieważ są one częścią biblioteki standardowej, które znajdują się w dowolnym środowisku kompilacji zgodny z C++.Po prostu użyć #include <string> dyrektywy, aby te typy dostępnych w programie.(Jeśli używasz MFC i ATL CString klasy jest również dostępna, ale nie jest częścią C++ standard.) Użycie tablic zakończonego znakiem null (ciągi stylu języka C, wyżej wymienione) jest zdecydowanie odradzane nowoczesnego języka c++.Aby uzyskać więcej informacji na temat umożliwiające podjęcie decyzji, jakiego typu ciąg znaków do wykorzystania w nowoczesnej program w języku C++ i jak konwertować między różnymi rodzajami, zobacz Ciągi i tekst (C++ nowoczesny).
Typy zdefiniowane przez użytkownika
Gdy zdefiniowano class, struct, union, lub enum, że konstrukcja jest używana w pozostałej części kodu, jak gdyby był typu podstawowych.Posiada znany rozmiar w pamięci, a niektóre zasady, o tym, jak można używać go dotyczą dopiero w trakcie oraz, w czasie wykonywania, w przypadku obowiązywania programu.Podstawowe różnice między podstawowymi wbudowanych typów i typy zdefiniowane przez użytkownika są następujące:
Kompilator nie ma wbudowanego wiedzy typ zdefiniowany przez użytkownika.To "uczy się" typu po napotkaniu najpierw definicji podczas procesu kompilacji.
Można określić, jakie operacje mogą być wykonywane od typu, i jak go można konwertować na inne typy, definiując (za pośrednictwem przeciążenia) właściwych podmiotów gospodarczych, albo jako członkowie klasy lub funkcje Państw.Aby uzyskać więcej informacji, zobacz Przeciążenie.
Nie muszą być statycznie wpisane (reguła, że obiekt nigdy nie typu zmian).Za pomocą mechanizmów dziedziczenia i polimorfizmu, Zmienna zadeklarowana jako typ zdefiniowany przez użytkownika klasy (nazywany danego wystąpienia obiektu klasy) może mieć inny typ w czasie wykonywania, niż w czasie kompilacji.Aby uzyskać więcej informacji, zobacz Klasy pochodne.
Typami wskaźników
Pochodzącym z najbliższej wersji języka C, C++ nadal pozwalają deklaruje zmienną typu wskaźnik przy użyciu specjalnych oświadczenie * (gwiazdka).Typ wskaźnika przechowuje adres lokalizacji w pamięci przechowywania wartości rzeczywiste dane.W nowoczesnych C++, nazywa się jako surowych wskaźnikówi są dostępne w kodzie poprzez specjalne operatory * (gwiazdka) lub -> (kreska z większa-niż).Jest to odwołaniem odniesienia do, i który z nich, których używasz zależy od tego, czy są odwołaniem odniesienia do wskaźnika na wartość skalarną lub wskaźnika do elementu członkowskiego w obiekcie.Praca z typami wskaźników od dawna jednym z najtrudniejszych i mylące aspekty rozwoju programu C i C++.W tej sekcji opisano niektóre fakty i aby nie używać surowych wskaźników, jeśli chcesz, aby, ale nowoczesnego języka c++, to ma już wymagane (lub zalecane) na potrzeby surowych wskaźników własności obiektów w ogóle, ze względu na ewolucję inteligentnego wskaźnika (dokładniej omówione na końcu tej sekcji).To nadal jest użyteczne i bezpieczne w użyciu surowych wskaźników do obserwacji obiektów, ale jeśli można ich na własność obiektu, należy skorzystać z ostrożnością i bardzo uważnym rozważeniu jak obiektów posiadanych przez nich są tworzone i niszczone.
Pierwszą rzeczą, którą trzeba wiedzieć jest Deklarując zmienną surowego wskaźnik będą przydzielane tylko pamięci jest wymagana do przechowywania adresu lokalizacji w pamięci, który wskaźnik będzie odnosić się do kiedy to wyświetlono.Przydzielanie pamięci dla samych wartości danych (zwane również magazyn zapasowy) nie jest jeszcze przydzielona.Innymi słowy przez zadeklarowanie zmiennej wskaźnik surowego, tworzysz zmienną adres pamięci, nie jest zmienna rzeczywiste dane.Odwołaniem odniesienia do zmiennej wskaźnik przed upewniając się, że zawiera prawidłowy adres magazynu kopii spowoduje, że nie zdefiniowano zachowania (zazwyczaj błąd krytyczny) w programie.W poniższym przykładzie zademonstrowano tego rodzaju błąd:
int* pNumber; // Declare a pointer-to-int variable.
*pNumber = 10; // error. Although this may compile, it is
// a serious error. We are dereferencing an
// uninitialized pointer variable with no
// allocated memory to point to.
Przykład rozstrzyga typ wskaźnika, bez potrzeby wszystkie pamięci przydzielonej na przechowywanie danych rzeczywistych liczb całkowitych lub adres pamięci prawidłowe przypisane do niego.Poniższy kod poprawiania tych błędów:
int number = 10; // Declare and initialize a local integer
// variable for data backing store.
int* pNumber = &number; // Declare and initialize a local integer
// pointer variable to a valid memory
// address to that backing store.
...
*pNumber = 41; // Dereference and store a new value in
// the memory pointed to by
// pNumber, the integer variable called
// “number”. Note “number” was changed, not
// “pNumber”.
Przechowywania pamięci stosu lokalnych poprawny kod przykład zastosowania, aby utworzyć wsparcie ze strony, która pNumber punktów.Dla uproszczenia możemy użyć typu podstawowych.W praktyce zapasowego magazynu dla wskaźników są większości typów często zdefiniowanej przez użytkownika, które są dynamicznie przydzielane na danym obszarze pamięci o nazwie sterty (lub "wolna store") przy użyciu new wyrażenie słowa kluczowego (w stylu języka C Programowanie, starszy malloc() została użyta funkcja biblioteczna C runtime).Po przydzielone, te "zmienne" są zwykle określane jako "obiektów", zwłaszcza, jeśli są one oparte na definicji klasy.Pamięć zarezerwowana z new muszą zostać usunięte przez odpowiednie delete instrukcję (lub, jeśli użyto malloc() funkcja dokonanie jego funkcji środowiska wykonawczego języka C free()).
Jednakże, nietrudno zapomnienie dynamicznie przydzielane obiektu-szczególnie w skomplikowany kod, który powoduje błąd zasobu o nazwie przeciek pamięci.Z tego powodu stosowania surowych wskaźników zdecydowanie odradza się nowoczesnego języka c++.Jest prawie zawsze lepiej, aby otoczyć surowego wskaźnika w inteligentnego wskaźnika, który będzie automatycznie zwolnić pamięć podczas jego destruktora jest wywoływana, (gdy kod wykracza poza zakres dla inteligentnego wskaźnika); za pomocą Sprytne wskaźniki praktycznie wyeliminować programów C++ całej klasy usterek.W poniższym przykładzie przyjęto założenie, MyClass jest zdefiniowany przez użytkownika typ, który ma publicznej metodyDoSomeWork();
void someFunction() {
unique_ptr<MyClass> pMc(new MyClass);
pMc->DoSomeWork();
}
// No memory leak. Out-of-scope automatically calls the destructor
// for the unique_ptr, freeing the resource.
Aby uzyskać więcej informacji o wskaźnikach inteligentnych, zobacz Inteligentne kursory (Podręcznik programowania C++ nowoczesny).
Aby uzyskać więcej informacji na temat wskaźnik konwersji, zobacz Typ konwersji i typ bezpieczeństwa (C++).
Aby uzyskać więcej informacji o wskaźnikach ogólnie rzecz biorąc, zobacz Wskaźniki.
Typy danych systemu Windows
W klasycznym Win32 programowania C i C++, większość funkcji użyć definicje typów specyficznych dla systemu Windows i #define makra (zdefiniowane w windef.h) do określenia rodzajów parametrów i zwracają wartości.Te "typów danych Windows" są głównie tylko ze specjalnymi nazw (aliasy) do wbudowanych typów C/C++.Aby uzyskać pełną listę tych definicje typów i preprocesora definicji, zobacz Windows Data Types.Niektóre definicje tych typów, takich jak HRESULT i LCID, są użyteczne i opisowe.Inne, takie jak INT, nie mają specjalnego znaczenia i są aliasami tylko dla podstawowych typów C++.Inne typy danych systemu Windows mają nazwy, które są zachowywane od czasów programowania C i 16-bitowe procesory i nie mają celu lub znaczenie na nowoczesnego sprzętu lub systemów operacyjnych.Istnieją również typy danych specjalne związane z bibliotekę uruchomieniową systemu Windows, który jest wymieniony jako Windows Runtime base data types.W nowoczesnych C++ ogólne wytyczne jest wolą typy podstawowe języka C++, chyba że typu Windows komunikuje się pożyteczna dodatkowych o tym, jak wartość jest interpretowane.
Więcej informacji
Aby uzyskać więcej informacji o systemie typu C++ zobacz następujące tematy.
W tym artykule opisano typów wartości wraz z zagadnień odnoszących się do ich wykorzystania. |
|
W tym artykule opisano typowe problemy przy konwersji typu i przedstawiono sposób uniknąć ich. |