2012-01-10 17 views
52

Załóżmy, że mamy klasę szablonu Area, która ma zmienną składową T area, a także funkcje składową T getArea() i void setArea(T).Dziedziczenie z klasy szablonu w języku C++

Mogę utworzyć obiekt określonego rodzaju Area, wpisując Area<int>.

Teraz mam klasę Rectangle, która dziedziczy klasę Area. Ponieważ sama Rectangle nie jest szablonem, nie mogę wpisać Rectangle<int>.

Jak specjalizować odziedziczony obiekt Area dla obiektów Rectangle?

EDYCJA: Przepraszam, zapomniałem wyjaśnić - moje pytania dotyczą tego, czy możliwe jest dziedziczenie Obszaru bez specjalizacji, więc nie jest ono dziedziczone jako Obszar int, ale jako Obszar Obszaru może specjalizować typy.

+1

Jest to szablon klasy _, ponieważ jest to szablon, z którego generowane są klasy. – sbi

Odpowiedz

138

szablony do zrozumienia, że ​​to ogromne korzyści, aby uzyskać terminologii prosto ponieważ sposób mówić o t hem określa 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 jest obiekt , a nie, ale oczywiście można utworzyć obiekt z tej klasy w ten sam sposób, w jaki można tworzyć obiekty z dowolnej innej klasy). Kolejną taką klasą byłby Area<char>. Zauważ, że są to całkowicie różne klasy, które nie mają ze sobą nic wspólnego poza faktem, że zostały wygenerowane z tego samego szablonu klasy.

Ponieważnie jest klasą, nie można wyprowadzić z niego klasy Rectangle. Możesz wyprowadzić klasę tylko z innej klasy (lub kilku z nich).Od Area<int> jest klasa, można, na przykład, czerpią Rectangle od niego:

class Rectangle: 
    public Area<int> 
{ 
    // ... 
}; 

ponieważ Area<int> i Area<char> są różne klasy, można nawet czerpać z obu jednocześnie (jednak przy dostępie członków nich, będziesz mieć do czynienia z dwuznaczności):

class Rectangle: 
    public Area<int>, 
    public Area<char> 
{ 
    // ... 
}; 

jednak trzeba określić, które klasyfikowane w celu uzyskania od kiedy można zdefiniować Rectangle. Jest to prawdą niezależnie od tego, czy te klasy są generowane z szablonu, czy nie. Dwa obiekty tej samej klasy po prostu nie mogą mieć różnych hierarchii dziedziczenia.

Co można zrobić, aby szablon był również szablonem Rectangle. Jeśli piszesz

template<typename T> class Rectangle: 
    public Area<T> 
{ 
    // ... 
}; 

Masz szablon Rectangle, z którego można uzyskać klasę Rectangle<int> wynikającemu z Area<int> i inną klasę Rectangle<char> wynikającemu z Area<char>.

Możliwe, że chcesz mieć pojedynczy typ Rectangle, dzięki czemu możesz przekazać wszystkie rodzaje Rectangle do tej samej funkcji (która sama nie musi znać typu obszaru). Ponieważ klasy Rectangle<T> wygenerowane przez utworzenie szablonu Rectangle są formalnie niezależne od siebie, nie działa w ten sposób. Można jednak skorzystać z wielokrotne dziedziczenie tutaj:

class Rectangle // not inheriting from any Area type 
{ 
    // Area independent interface 
}; 

template<typename T> class SpecificRectangle: 
    public Rectangle, 
    public Area<T> 
{ 
    // Area dependent stuff 
}; 

void foo(Rectangle&); // A function which works with generic rectangles 

int main() 
{ 
    SpecificRectangle<int> intrect; 
    foo(intrect); 

    SpecificRectangle<char> charrect; 
    foo(charrect); 
} 

Jeśli ważne jest, że generyczny Rectangle jest pochodną ogólnej Area można zrobić tę samą sztuczkę z Area też:

class Area 
{ 
    // generic Area interface 
}; 

class Rectangle: 
    public virtual Area // virtual because of "diamond inheritance" 
{ 
    // generic rectangle interface 
}; 

template<typename T> class SpecificArea: 
    public virtual Area 
{ 
    // specific implementation of Area for type T 
}; 

template<typename T> class SpecificRectangle: 
    public Rectangle, // maybe this should be virtual as well, in case the hierarchy is extended later 
    public SpecificArea<T> // no virtual inheritance needed here 
{ 
    // specific implementation of Rectangle for type T 
}; 
4

Rectangle będzie musiał być szablonem, w przeciwnym razie jest to tylko jeden typ. Nie może to być szablon, podczas gdy jego podstawa jest magiczna. (Jego bazowa może być szablon instancji, choć wydają się chce utrzymać funkcjonalność bazy za jako szablon.)

7
class Rectangle : public Area<int> { 
}; 
10

Czy po prostu staramy się czerpać z Area<int>? W takim przypadku to zrobić:

class Rectangle : public Area<int> 
{ 
    // ... 
}; 

EDIT: Po wyjaśnieniu, wydaje jesteś rzeczywiście próbuje zrobić Rectangle szablonu, jak również, w tym przypadku następujące powinny działać:

template <typename T> 
class Rectangle : public Area<T> 
{ 
    // ... 
}; 
5

Złóż prostokąt szablon i przekazać TypeName na do obszaru

template <typename T> 
class Rectangle : public Area<T> 
{ 

}; 
0
#include<iostream> 

using namespace std; 

template<class t> 
class base { 
protected: 
    t a; 
public: 
    base(t aa){ 
     a = aa; 
     cout<<"base "<<a<<endl; 
    } 
}; 

template <class t> 
class derived: public base<t>{ 
    public: 
     derived(t a): base<t>(a) { 
     } 
     //Here is the method in derived class 
    void sampleMethod() { 
     cout<<"In sample Method"<<endl; 
    } 
}; 

int main() { 
    derived<int> q(1); 
    // calling the methods 
    q.sampleMethod(); 
} 
+0

co jeśli masz metody w klasie pochodnej? Jak byś je zdefiniował? I najbardziej importować, przynajmniej dla mnie, w jaki sposób wywołać/użyć tych metod w funkcji main()? – Pototo

+0

Odpowiedź na twoje pytanie jest w kodzie –

+2

Po pierwsze, jest to naprawdę stare pytanie, które już ma świetną odpowiedź. Po drugie, unikaj odpowiedzi (i pytań), które są tylko kodem. Przydatne jest również zamieszczenie szczegółowych wyjaśnień. – marcman

Powiązane problemy