Moștenire și șabloane de clase
În cazul moștenirii unei clase bazate pe un șablon, trebuie să indicăm valorile pentru parametrii șablonului clasei de bază. În acest caz, putem de asemenea să definim clasa derivată ca șablon și să folosim parametrii acesteia pentru a seta parametrii clasei de bază:
#include <iostream>
template <typename T>
class Person {
public:
Person(T id, std::string name) : id{id}, name{name} { }
void print() const
{
std::cout << "Id: " << id << "\tName: " << name << std::endl;
}
protected:
T id;
std::string name;
};
template <typename T>
class Employee: public Person<T> {
public:
Employee(T id, std::string name, std::string company) : Person<T>{id, name}, company{company} { }
void print() const
{
Person<T>::print();
std::cout << Person<T>::name << " works in " << company << std::endl;
}
private:
std::string company;
};
int main()
{
Employee<unsigned> bob{123, "Bob", "Google"};
bob.print(); // Id: 123 Name: Bob
// Bob works in Google
}
În acest caz, la început este definit șablonul clasei de bază Person, care folosește parametrul T pentru a seta tipul variabilei id. Apoi este definită clasa-șablon Employee, care moștenește de la Person:
template <typename T>
class Employee: public Person<T>
Astfel, pentru clasa de bază ca parametru al șablonului va fi utilizată valoarea care este determinată de șablonul Employee.
Pentru a apela funcționalitatea clasei de bază, este necesar să folosim expresia Person<T> (adică să indicăm valoarea parametrului șablonului Person):
Person<T>{id, name} // apelarea constructorului
Person<T>::print(); // apelarea funcției print
Person<T>::name // accesarea variabilei name din clasa de bază Person
Mai departe în program putem tipiza obiectele Employee cu un anumit tip, iar acest tip va fi aplicat funcționalității clasei de bază:
Employee<unsigned> bob{123, "Bob", "Google"};
O altă variantă de moștenire constă în faptul că la momentul moștenirii stabilim explicit tipurile folosite pentru clasa de bază:
#include <iostream>
template <typename T>
class Person {
public:
Person(T id, std::string name) : id{id}, name{name} { }
void print() const
{
std::cout << "Id: " << id << "\tName: " << name << std::endl;
}
protected:
T id;
std::string name;
};
class Employee: public Person<unsigned> {
public:
Employee(unsigned id, std::string name, std::string company) : Person{id, name}, company{company} { }
void print() const
{
Person::print();
std::cout << name << " works in " << company << std::endl;
}
private:
std::string company;
};
int main()
{
Employee bob{123, "Bob", "Google"};
bob.print(); // Id: 123 Name: Bob
// Bob works in Google
}
În acest caz, clasa Employee este o clasă obișnuită care moștenește de la Person<unsigned>. Adică, pentru funcționalitatea clasei de bază, parametrul T va reprezenta tipul unsigned.