Şablonları anlamak için, terminolojiyi doğru anlamak çok büyük bir avantajdır çünkü onlar hakkında konuşma şekliniz onlar hakkında düşünme şeklinizi belirler.
Özellikle, Area
bir şablon sınıf değil, bir sınıf şablonudur. Yani, sınıfların üretilebileceği bir şablondur. Area<int>
böyle bir sınıftır (bu bir nesne değildir , ancak elbette, başka herhangi bir sınıftan nesneler oluşturabildiğiniz yollarla o sınıftan bir nesne oluşturabilirsiniz). Böyle bir başka sınıf olacaktır Area<char>
. Bunların tamamen farklı sınıflar olduğunu ve aynı sınıf şablonundan oluşturulmuş olmaları dışında hiçbir ortak yanları olmadığını unutmayın.
Yana Area
bir sınıf değil, sınıfı elde edemez Rectangle
ondan. Yalnızca başka bir sınıftan (veya birkaçından) bir sınıf türetebilirsiniz. Yana Area<int>
bir sınıftır, sen, örneğin, elde edebileceğini Rectangle
ondan:
class Rectangle:
public Area<int>
{
// ...
};
Yana Area<int>
ve Area<char>
farklı sınıflar vardır, aynı anda (bunların üyelerini erişirken ancak, belirsizlikleri ile uğraşmak gerekecek) her iki kaynaklanıyor bile yapabilirsiniz:
class Rectangle:
public Area<int>,
public Area<char>
{
// ...
};
Bununla birlikte, tanımladığınızda hangi sınıflandırmanın türetileceğini belirtmeniz gerekir Rectangle
. Bu, bu sınıfların bir şablondan oluşturulmuş olup olmadığına bakılmaksızın geçerlidir. Aynı sınıftaki iki nesnenin farklı miras hiyerarşileri olamaz.
Yapabileceğiniz şey Rectangle
bir şablon yapmaktır . Eğer yazarsan
template<typename T> class Rectangle:
public Area<T>
{
// ...
};
Bir şablon var Rectangle
bir sınıf alabilirsiniz hangi Rectangle<int>
türetilmiştir Area<int>
ve farklı bir sınıf Rectangle<char>
türetilmiştir Area<char>
.
Tek bir türe sahip olmak isteyebilirsiniz, Rectangle
böylece her türden Rectangle
aynı işleve geçebilirsiniz (Alan türünü bilmesine gerek yoktur). Yana Rectangle<T>
örneklenimin tarafından oluşturulan sınıfları Rectangle
birbirinden resmen bağımsız, bu şekilde çalışmıyor. Bununla birlikte, burada çoklu kalıtımdan yararlanabilirsiniz:
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);
}
Jenerik ürününüzün bir jenerikten Rectangle
türetilmesi önemliyse Area
, aynı numarayı Area
da yapabilirsiniz:
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
};