Dziedziczenie z klasy szablonu w c++
Załóżmy, że mamy klasę szablonów Area
, która ma zmienną member T area
, A T getArea()
i void setArea(T)
Funkcje member.
Mogę utworzyć Area
obiekt określonego typu wpisując Area<int>
.
Teraz mam klasę Rectangle
, która dziedziczy klasę Area
. Ponieważ Rectangle
nie jest szablonem, nie mogę wpisać Rectangle<int>
.
Jak wyspecjalizować dziedziczony typ Area
dla Rectangle
obiektów?
EDIT: Przepraszam, zapomniałem wyjaśnić - moje pytania brzmią, czy jest możliwe Dziedzicz obszar bez specjalizowania go, więc nie jest dziedziczony jako obszar ints, ale jako obszar prostokąt może specjalizować typy dla.
6 answers
Dla zrozumienia szablonów, bardzo korzystne jest uporządkowanie terminologii, ponieważ sposób, w jaki o nich mówisz, decyduje o sposobie myślenia o nich.
W szczególności, Area
nie jest klasą szablonową, ale szablonem klasowym. Oznacza to, że jest to szablon, z którego można generować klasy. Area<int>
jest taką klasą (jest to a nie obiekt, ale oczywiście można utworzyć obiekt z tej klasy w taki sam sposób, jak można tworzyć obiekty z każdej innej klasy). Kolejny taki Klasa to Area<char>
. Zauważ, że są to zupełnie różne klasy, które nie mają nic wspólnego z wyjątkiem faktu, że zostały wygenerowane z tego samego szablonu klasy.
Ponieważ Area
nie jest klasą, nie można wyprowadzić z niej klasy Rectangle
. Możesz tylko wyprowadzić klasę z innej klasy (lub kilku z nich). Ponieważ Area<int>
jest klasą, można na przykład wyprowadzić Rectangle
z niej:
class Rectangle:
public Area<int>
{
// ...
};
Ponieważ Area<int>
i Area<char>
są różnymi klasami, można nawet czerpać z obu w w tym samym czasie (jednak przy dostępie do ich członków będziesz musiał poradzić sobie z niejednoznacznością): {]}
class Rectangle:
public Area<int>,
public Area<char>
{
// ...
};
Musisz jednak określić, z której klasy wywodzić się, gdy zdefiniujesz Rectangle
. Jest to prawdą 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 zrobić Rectangle
również szablon. Jeśli napiszesz
template<typename T> class Rectangle:
public Area<T>
{
// ...
};
Masz szablon Rectangle
z którego możesz otrzymać klasę Rectangle<int>
, która wywodzi się z Area<int>
, oraz inną klasę Rectangle<char>
, która wywodzi się z Area<char>
.
Może być tak, że chcesz mieć jeden typ Rectangle
, aby można było przekazać wszystkie rodzaje Rectangle
do tej samej funkcji (która sama nie musi znać typu obszaru). Ponieważ klasy Rectangle<T>
generowane przez utworzenie instancji szablonu Rectangle
są formalnie niezależne od siebie, nie działa to w ten sposób. Można jednak korzystać z wielu dziedziczeń 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, aby rodzajnik Rectangle
pochodzi od generyka Area
, możesz zrobić tę samą sztuczkę z Area
również:
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
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 21:16:49
Czy ty po prostu próbujesz czerpać z Area<int>
? W takim przypadku robisz to:
class Rectangle : public Area<int>
{
// ...
};
EDIT: po wyjaśnieniu, wydaje się, że próbujesz zrobić Rectangle
również szablon, w którym to przypadku powinno działać:
template <typename T>
class Rectangle : public Area<T>
{
// ...
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 22:43:40
class Rectangle : public Area<int> {
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 20:46:27
Rectangle
będzie musiał być szablonem, w przeciwnym razie jest to tylko jeden typ . Nie może być nie-szablonem, podczas gdy jego baza magicznie jest. (Jego bazą może być szablon instancja, choć wydaje się, że chcesz zachować funkcjonalność bazy jako szablon.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 20:44:24
Uczyń prostokąt szablonem i przekaż nazwę typową do obszaru:
template <typename T>
class Rectangle : public Area<T>
{
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-10 22:44:13
#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();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 17:32:21