Przegląd typów ogólnych w Visual C++
Generycznych są sparametryzowana typów obsługiwanych przez common language runtime.Sparametryzowana typem jest typ, który ma zdefiniowany parametr nieznany typ, który jest określony, gdy używany jest typowa.
Dlaczego generycznych?
C++ obsługuje szablonów i obu szablonów i generycznego wsparcia sparametryzowana typów do tworzenia wpisany Biblioteka klas.Jednak szablony udostępniają parametryzacji kompilacji.Nie można odwołać zestawu zawierającego definicję szablon i Utwórz nowe specjalizacje szablonu.Po skompilowany, specjalistyczne szablon wygląda jak inne klasy lub metody.Natomiast generycznych są emitowane w MSIL jako typ sparametryzowana znane w czasie wykonywania się sparametryzowana typu; Kod źródłowy, który odwołuje się do zestawu zawierającego typ rodzajowy można tworzyć specjalizacje typu rodzajowego.Więcej o porównanie szablonów języka Visual C++ i rodzajowych, zobacz Typy ogólne i szablony (Visual C++).
Ogólne funkcje i typy
Typy klas, tak długo, jak są one typy zarządzane, mogą być rodzajowy.Przykładem tego może być List klasy.Typ obiektu na liście byłoby parametru typu.Jeśli potrzebne są List klasy dla wielu różnych typów obiektów przed rodzajowych, być może użyto List pobierająca System::Object jako typ elementu.Ale które pozwoliłyby dowolnego obiektu (w tym obiektów niewłaściwego typu) ma być używany na liście.Wykaz taki zostanie poddana klasą kolekcji bez typu.W najlepszym przypadku można sprawdzić typ w czasie wykonywania i wyjątek.Lub może być używany jako szablon, który straci jego ogólna jakość raz kompilowane do zestawu.Konsumenci użytkownika zestawu nie może utworzyć własne specjalizacje szablonu.Generycznych pozwalają tworzyć wpisany Biblioteka klas, powiedz List<int> (Czytaj jako "Lista int") i List<double> ("Lista podwójne") który może wygenerować błąd kompilacji, jeśli próbowali umieścić typu, który był kolekcji nie przeznaczone do przyjęcia do wpisywanych kolekcji.Ponadto te typy rodzajowe po pozostają są kompilowane.
Opis składni klas rodzajowych można znaleźć w Klasy ogólne [C++/CLI]. nowy obszar nazw, System.Collections.Generic, wprowadzono zestaw typów kolekcji sparametryzowana, łącznie z Dictionary, List i LinkedList.Aby uzyskać więcej informacji, zobacz Typy ogólne w bibliotece klas programu .NET Framework (Przewodnik programowania w języku C#).
Zarówno wystąpienia i funkcje składowe klasy statycznej, delegatów i funkcje globalne mogą być również ogólne.Ogólne funkcje może być konieczne, jeśli parametry funkcji są nieznanego typu lub jeśli sama funkcja musi pracować z typami ogólnymi.W wielu przypadkach gdzie System::Object mogą zostać wykorzystane w przeszłości jako parametr dla danego typu obiektu nieznany parametr typu rodzajowego mogą być stosowane zamiast, co pozwala na więcej kodu typ palety.Każda próba przekazania na typ, który funkcja nie jest przeznaczone dla zostanie oznaczony jako błąd w czasie kompilacji.Za pomocą System::Object jako parametr funkcji, przypadkowego przekazywanie obiektu funkcji nie zamierza zajmować może nie zostać wykryte i trzeba by oddanych nieznany typ obiektu do określonego typu w treści funkcji i uwzględnia możliwości InvalidCastException.Ogólny kod próby przekazania obiektu do funkcji mogłoby spowodować konflikt typów więc gwarantuje mają poprawny typ treści funkcji.
Te same korzyści dotyczą kolekcja klas rodzajowych pod zabudowę.Użyć w klasach kolekcji w przeszłości System::Object do przechowywania elementów w kolekcji.Wstawiania obiektów określonego typu, Kolekcja nie jest przeznaczone dla nie została oflagowana, w czasie kompilacji, a często nawet w przypadku, gdy obiekty zostały wstawione.Zwykle obiektu mogłoby być rzutowane na innego typu, gdy było dostępne w kolekcji.Tylko wtedy, gdy obsady nie powiodło się nieoczekiwany typ można wykryć.Generycznych rozwiązuje ten problem w czasie kompilacji, wykrywając wszelki kod, który wstawia typu, który nie pasuje (lub niejawnie przekonwertować) parametr typu rodzajowego kolekcji.
Opis składni, zobacz Funkcje ogólne (C++/CLI).
Terminologia używana z rodzajowych
Parametry typu
Ogólna deklaracja zawiera jeden lub więcej typów nieznany znane jako parametrów typu.Parametry typu podane są nazwy, która oznacza typ w treści deklaracji rodzajowy.Parametr typu jest używany jako typ w treści deklaracji rodzajowy.Rodzajowy zgłoszenia do listy<T> zawiera parametr typu T.
Argumentów typu
Argument typu jest rzeczywisty typ używać zamiast parametru typu specjalizuje się typowa dla określonego typu lub typów.Na przykład int jest argumentem typu w List<int>.Typy wartości i typy uchwyt to jedyne typy dozwolone w jako argument typu rodzajowego.
Typ konstruowanej
Typ zbudowane z typu rodzajowego jest określany jako skonstruowane typu.Typ, nie w pełni określony, takich jak List<T> jest typu otwartego konstruowanej; Typ w pełni określony, takich jak List<double>, jest zamkniętego typu konstruowanej lub wyspecjalizowany typ.Otwórz typy konstruowanej mogą być używane w definicji innych typów ani metod ogólnych i nie mogą być całkowicie określone aż otaczający rodzajowy jest określona.Na przykład następujące jest użycie otwartego typu skonstruowane jako klasa podstawowa dla rodzajowego:
// generics_overview.cpp
// compile with: /clr /c
generic <typename T>
ref class List {};
generic <typename T>
ref class Queue : public List<T> {};
Ograniczenia
Ograniczenie jest ograniczeniem typu, które mogą zostać wykorzystane jako parametru typu.Na przykład danej klasy rodzajowej może akceptować tylko klasy, które dziedziczą z określonej klasy lub wykonania określonego interfejsu.Aby uzyskać więcej informacji, zobacz Ograniczenia parametrów typu ogólnego (C++/CLI).
Typy wartości i typy odwołań
Uchwyty typów i typy wartości może służyć jako argumentów typu.W definicji ogólny, w którym można użyć typu, składnia jest to, że typy odwołań.Na przykład —> operator jest używany do dostępu do elementów członkowskich typu parametru typu Typ ostatecznie używany jest typ odwołania lub typ wartości czy też nie.Typ wartości jest używana jako argument typ, środowiska wykonawczego generuje kod, który używa typów wartości bezpośrednio, bez boksie typów wartości.
Korzystając z typem odwołania jako argument typu rodzajowego, składnią uchwyt.Korzystając z typem wartości jako argumentu typu rodzajowego, bezpośrednio użyć nazwy typu.
// generics_overview_2.cpp
// compile with: /clr
generic <typename T>
ref class GenericType {};
ref class ReferenceType {};
value struct ValueType {};
int main() {
GenericType<ReferenceType^> x;
GenericType<ValueType> y;
}
Parametry typu
Parametry typu rodzajowego klasy są traktowane jak inne identyfikatory.Jednakże ponieważ typ nie jest znana, istnieją ograniczenia dotyczące ich zastosowania.Na przykład nie można używać członków i metod klasy parametr typu, chyba że parametr typu jest znany do obsługi tych członków.To znaczy członka dostęp za pośrednictwem parametru typu, należy dodać typ, który zawiera element członkowski do listy ograniczenia parametru typu.
// generics_overview_3.cpp
// compile with: /clr
interface class I {
void f1();
void f2();
};
ref struct R : public I {
virtual void f1() {}
virtual void f2() {}
virtual void f3() {}
};
generic <typename T>
where T : I
void f(T t) {
t->f1();
t->f2();
safe_cast<R^>(t)->f3();
}
int main() {
f(gcnew R());
}
Ograniczenia te dotyczą również operatorów.Nie można używać jako parametr typu rodzajowego swobodne == i != podmioty gospodarcze do porównywania dwóch wystąpień parametru typu, w przypadku, gdy typ nie obsługuje tych operatorów.Kontrole takie są niezbędne dla rodzajowych, ale nie dla szablonów, ponieważ rodzajowych może być wyspecjalizowany w czasie wykonywania dowolnej klasy spełniającego ograniczenia, kiedy jest już za późno do sprawdzenia wykorzystania nieprawidłowe elementy.
Domyślne wystąpienie parametru typu mogą być tworzone za pomocą () operatora.Na przykład:
T t = T();
gdzie T , to parametr typu rodzajowego definicji klasy lub metody, inicjuje zmienną na wartość domyślną.Jeśli T jest klasą ref, będzie on pusty wskaźnik; Jeśli T jest klasą wartości obiektu ustawiana jest wartość zero.Jest to tak zwane domyślne inicjator.