25
loading...
This website collects cookies to deliver better user experience
Student
:class Student{
private:
std::string temp;
int data;
public:
Student(std::string t, int d){
temp = t;
data = d;
}
int getdata(){
return data;
}
std::string getstring(){
return temp;
}
};
string
and a double
as it's data members, normally we could just write another class with the same content but with a different name and change the int
to double
but that can get tedious and lengthy especially when it's a class with lots of content and it can make your code look unappealing, but class templates make things so much easier because we can write just one class that will serve as a template if we need a similar class, lets do that with the Student
class:#include <iostream>
template<typename S>
class Student{
template<typename T> //this is for the overloading of the << operator
friend std::ostream &operator<<(std::ostream &os, const Student<T> &rhs);
private:
std::string temp;
S data;
public:
Student(std::string t, S d){
temp = t;
data = d;
}
S getdata() const{
return data;
}
std::string getstring() consr{
return temp;
}
};
template<typename S> //another template is needed since the ones above can't be reused
std::ostream &operator<<(std::ostream &os, const Student<S> &rhs){
os << "Name: " << rhs.getstring() << " Data: " << rhs.getdata();
return os;
}
I overloaded the stream insertion <<
operator so i can output Student
objects easier
I suggest you read the former article on function templates before this one
template<typename S>
that will be used to make the data
attribute in the class able to model any data type, so we replaced the int
with our template parameter S
and that's basically it, now we can create a Student
object that will have the ability to have a string
with a double
, float
, other data types, now we create a Student
object like this:int main(){
Student<double> padawan{"Padawan", 3.6};
std::cout << padawan.getdata() << std::endl; //3.6
Student<std::string> erik{"erik", "human"};
std::cout << erik.getdata() << std::endl; //human
Student<Student<int>> casey{"casey", {"glory", 16}};
std::cout << casey.getstring() << std::endl; // casey
std::cout << casey.getdata() << std::endl; // Name: glory Data: 16
//or
std::cout << casey.getdata().getstring() << std::endl; // glory
std::cout << casey.getdata().getdata() << std::endl; // 16
return 0;
}
Student
object that could model a string
and other data types, you can make the two attributes to be templates, i.e X temp
and S data
but you would have to add that to the template parameter template<typename X, typename S>
so the compiler knows what X
is. Notice that i even modeled a Student object with a string
and another Student
object in it, if you can utilize it these templates properly it can save you writing a lot of unnecessary code, Also the syntax we used in creating these Student
objects might look familiar to when you create a vector
object like std::vector<int> vec{1,2,3};
, that's because vectors too are also template classes behind the scenes, the same goes for other C++ containers like deques, maps, links e.t.c. So that's it, this a just a basic look into class templates, it can get very complex when you mix in stuff like inheritance, polymorphism e.t.c. Here's the source code for what i showed you so far in case you want to copy it into your IDE:#include <iostream>
template<typename S>
class Student{
template<typename T>
friend std::ostream &operator<<(std::ostream &os, const Student<T> &rhs);
private:
std::string temp;
S data;
public:
Student(std::string t, S d) :temp{t}, data{d}{
}
S getdata() const{
return data;
}
std::string getstring() const{
return temp;
}
};
template<typename S>
std::ostream &operator<<(std::ostream &os, const Student<S> &rhs){
os << "Name: " << rhs.getstring() << " Data: " << rhs.getdata();
return os;
}
int main(){
Student<double> padawan{"Padawan", 3.6};
std::cout << padawan.getdata() << std::endl; //3.6
Student<std::string> erik{"erik", "human"};
std::cout << erik.getdata() << std::endl; //human
Student<Student<int>> casey{"casey", {"glory", 16}};
std::cout << casey.getstring() << std::endl; // casey
std::cout << casey.getdata() << std::endl; // Name: glory Data: 16
//or
std::cout << casey.getdata().getstring() << std::endl; // glory
std::cout << casey.getdata().getdata() << std::endl; // 16
return 0;
}
25