Untuk memahami template, sangat bermanfaat untuk meluruskan terminologinya karena cara Anda membicarakannya menentukan cara memikirkannya.
Secara khusus, Areaini bukan kelas template, tapi template kelas. Artinya, ini adalah template tempat kelas dapat dibuat. Area<int>adalah kelas seperti itu (ini bukan objek, tetapi tentu saja Anda dapat membuat objek dari kelas itu dengan cara yang sama seperti Anda membuat objek dari kelas lain). Kelas lain seperti itu Area<char>. Perhatikan bahwa itu adalah kelas yang sama sekali berbeda, yang tidak memiliki kesamaan apa pun kecuali fakta bahwa mereka dihasilkan dari template kelas yang sama.
Karena Areabukan kelas, Anda tidak dapat memperoleh kelas Rectangledarinya. Anda hanya dapat memperoleh satu kelas dari kelas lain (atau beberapa di antaranya). Karena Area<int>merupakan sebuah kelas, Anda dapat, misalnya, mengambil Rectangledarinya:
class Rectangle:
public Area<int>
{
// ...
};
Karena Area<int>dan Area<char>merupakan kelas yang berbeda, Anda bahkan dapat mengambil keduanya pada saat yang sama (namun saat mengakses anggota mereka, Anda harus berurusan dengan ambiguitas):
class Rectangle:
public Area<int>,
public Area<char>
{
// ...
};
Namun Anda harus menentukan kelas mana yang akan diturunkan saat Anda menentukan Rectangle. Ini benar tidak peduli apakah kelas-kelas itu dihasilkan dari template atau tidak. Dua objek dari kelas yang sama tidak dapat memiliki hierarki pewarisan yang berbeda.
Yang bisa Anda lakukan adalah membuat Rectangletemplate juga. Jika Anda menulis
template<typename T> class Rectangle:
public Area<T>
{
// ...
};
Anda memiliki template Rectangledari mana Anda bisa mendapatkan kelas Rectangle<int>asal Area<int>, dan kelas lain Rectangle<char>asal Area<char>.
Mungkin Anda ingin memiliki satu tipe Rectanglesehingga Anda bisa meneruskan semua jenis Rectangleke fungsi yang sama (yang tidak perlu mengetahui tipe Area). Karena Rectangle<T>kelas yang dibuat dengan membuat contoh template Rectanglesecara formal tidak bergantung satu sama lain, cara kerjanya tidak seperti itu. Namun Anda dapat menggunakan beberapa warisan di sini:
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);
}
Jika penting bahwa generik Anda Rectanglediturunkan dari generik, AreaAnda juga dapat melakukan trik yang sama Area:
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
};