para la comprensión de las plantillas, es de gran ventaja para conseguir la terminología recta debido a su forma de hablar acerca de t el dobladillo determina la manera de pensar sobre ellos.
Específicamente, Area
no es una clase de plantilla, sino una plantilla de clase. Es decir, es una plantilla a partir de la cual se pueden generar clases. Area<int>
es una clase (es no objeto, pero por supuesto puede crear un objeto de esa clase de la misma manera que puede crear objetos de cualquier otra clase). Otra de esas clases sería Area<char>
. Tenga en cuenta que esas son clases completamente diferentes, que no tienen nada en común, excepto por el hecho de que se generaron a partir de la misma plantilla de clase.
Dado que Area
no es una clase, no puede derivar la clase Rectangle
de ella. Solo puedes derivar una clase de otra clase (o varias de ellas).Desde Area<int>
es una clase, usted podría, por ejemplo, se derivan Rectangle
de ella:
class Rectangle:
public Area<int>
{
// ...
};
Desde Area<int>
y Area<char>
distintas clases, incluso se puede derivar de ambos en el mismo tiempo (sin embargo, cuando se accede a los miembros de ellas, que tendrá que hacer frente a las ambigüedades):
class Rectangle:
public Area<int>,
public Area<char>
{
// ...
};
Sin embargo, usted tiene que especificar cuál clasifica para derivar a partir de cuando se define Rectangle
. Esto es cierto independientemente de si esas clases se generan a partir de una plantilla o no. Dos objetos de la misma clase simplemente no pueden tener diferentes jerarquías de herencia.
Lo que puedes hacer es hacer también una plantilla en Rectangle
. Si se escribe
template<typename T> class Rectangle:
public Area<T>
{
// ...
};
tiene una plantilla Rectangle
a partir del cual se puede obtener una clase que deriva de Rectangle<int>
Area<int>
, y una clase diferente Rectangle<char>
que se deriva de Area<char>
.
Puede ser que desee tener un solo tipo Rectangle
para poder pasar todo tipo de Rectangle
a la misma función (que no necesita conocer el tipo de área). Como las clases Rectangle<T>
generadas al crear instancias de la plantilla Rectangle
son formalmente independientes entre sí, no funciona de esa manera. Sin embargo, usted puede hacer uso de la herencia múltiple aquí:
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);
}
Si es importante que su genérico Rectangle
se deriva de un genérico Area
que puede hacer el mismo truco con Area
también:
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
};
Es una "plantilla de clase" porque es una plantilla a partir de la cual se generan las clases. – sbi