Powiedzmy, że mamy klasę szablonu Area
, która ma zmienną składową T area
, a T getArea()
i void setArea(T)
funkcje składowe.
Potrafię stworzyć Area
obiekt określonego typu pisząc Area<int>
.
Teraz mam klasę, Rectangle
która dziedziczy Area
klasę. Ponieważ Rectangle
sam w sobie nie jest szablonem, nie mogę pisać Rectangle<int>
.
Jak wyspecjalizować dziedziczony Area
typ Rectangle
obiektów?
EDYCJA: Przepraszam, zapomniałem wyjaśnić - moje pytanie dotyczy tego, czy można dziedziczyć Area bez specjalizacji, więc nie jest ona dziedziczona jako Area of ints, ale ponieważ Area Rectangle może specjalizować typy.
c++
templates
inheritance
dtech
źródło
źródło
Odpowiedzi:
Zrozumienie szablonów ma ogromne znaczenie dla zrozumienia terminologii, ponieważ sposób, w jaki o nich mówisz, determinuje sposób myślenia o nich.
W szczególności
Area
nie jest klasą szablonu, ale szablonem klasy. Oznacza to, że jest to szablon, z którego można generować klasy.Area<int>
jest taką klasą (to nie jest obiekt, ale oczywiście możesz stworzyć obiekt z tej klasy w taki sam sposób, jak tworzysz obiekty z dowolnej innej klasy). Byłaby inna taka klasaArea<char>
. Zauważ, że są to zupełnie różne klasy, które nie mają ze sobą nic wspólnego poza tym, że zostały wygenerowane z tego samego szablonu klas.Ponieważ
Area
nie jest klasą, nie możesz wyprowadzićRectangle
z niej klasy . Możesz wyprowadzić klasę tylko z innej klasy (lub kilku z nich). PonieważArea<int>
jest to klasa, możesz na przykład wyprowadzićRectangle
z niej:Ponieważ
Area<int>
iArea<char>
są różnymi klasami, możesz nawet wyprowadzać z obu jednocześnie (jednak podczas uzyskiwania dostępu do ich członków będziesz musiał poradzić sobie z niejasnościami):Jednak podczas definiowania musisz określić, z których klas ma pochodzić
Rectangle
. Dzieje się tak bez względu na to, czy te klasy są generowane z szablonu, czy nie. Dwa obiekty tej samej klasy po prostu nie mogą mieć różnych hierarchii dziedziczenia.Możesz także zrobić
Rectangle
szablon. Jeśli piszeszMasz szablon,
Rectangle
z którego możesz pobrać klasę, zRectangle<int>
której pochodziArea<int>
, i inną klasę, zRectangle<char>
której pochodziArea<char>
.Może się zdarzyć, że chcesz mieć jeden typ
Rectangle
, aby móc przekazywać różne rodzajeRectangle
do tej samej funkcji (która sama nie musi znać typu obszaru). PonieważRectangle<T>
klasy generowane przez tworzenie wystąpienia szablonuRectangle
są formalnie niezależne od siebie, nie działa to w ten sposób. Możesz jednak skorzystać z wielokrotnego dziedziczenia tutaj:Jeśli ważne jest, aby Twój rodzajowy
Rectangle
wywodził się z generycznegoArea
, możesz zrobić tę samą sztuczkę zArea
:źródło
Czy po prostu próbujesz wyprowadzić
Area<int>
? W takim przypadku robisz to:EDYCJA: Po wyjaśnieniu wygląda na to, że faktycznie próbujesz również utworzyć
Rectangle
szablon, w takim przypadku następujące czynności powinny działać:źródło
źródło
Uczyń Rectangle szablonem i przekaż nazwę typu do Area:
źródło
Rectangle
będzie musiał być szablonem, w przeciwnym razie jest to tylko jeden typ . Nie może być nie szablonem, podczas gdy jego podstawa jest magicznie. (Jego podstawą może być wystąpienie szablonu , chociaż wydaje się, że chcesz zachować funkcjonalność bazy jako szablonu ).źródło
źródło