Professional Documents
Culture Documents
11 - TemplatesPart2Classes
11 - TemplatesPart2Classes
++C
Class templates – motivation:
class intClass {
int _member;
public:
void print() const;
};
class floatClass {
float _member;
public:
void print() const;
};
2
++C
Class templates
3
++C
Class templates
The code is similar to template functions:
• Add template<…> statement before the class
definition
• Use template argument as type in class definition
• To implement methods outside the class definition:
template <class T>
void genericClass<T>::print() const
{
std::cout << _member;
}
4
++C
Class template instantiation
(only explicit)
int main() {
genericClass<int> intObj;
genericClass<float> floatObj;
...
}
5
What is printed? ++C
7
++C
Templates with several arguments
template <class T1, class T2>
class A
{
T1 _d;
T2 _c;
};
int main()
{
A<double, int> a;
}
8
++C
Templates with several arguments
template <class T, class U>
void f(T x, U y) {
cout << x << “, ” << y << endl;
};
int main()
{
f( 90 , 1.4);
f<int, short>( 90 , 1.4 );
f<char>( 90 , 1.4 );
}
9
++C
Templates with several arguments
template <class T, class U>
void f(T x, U y) {
cout << x << “, ” << y << endl;
};
int main()
{
f( 90 , 1.4); 90, 1.4
f<int, short>( 90 , 1.4 ); 90, 1
f<char>( 90 , 1.4 ); Z, 1.4
}
10
++C
Are template type parameters enough?
class Buffer
{
int m_values[10];
};
class Buffer
{
int m_values[20];
};
Buffer<char,1024> buff2;
Buffer<int, 256> buff3;
T m_values[Size];
};
Buffer<char> buff1;
Buffer<> buff2; // same as Buff1, needs <>
Buffer<int, 256> buff3;
13
++C
Template and Types
• Buffer is not a type
• Buffer<char,1024> is a type
• Buffer<>, Buffer<char>,
Buffer<char,1024> are three names for the
same type
14
Templates specialization
17
++C
Class template specialization
template <class Type>
class A { ... }; int main()
{
template<>
class A<char*> A<int> ai(5);
{ ai.isBigger(7);
public: //generic isBigger()
char* _data;
A(char* data) : _data(data) { }
A<char*> as("hi");
bool isBigger(char* data);
}; as.isBigger("bye");
18
++C
Specialization of a single method
template <class Type>
class A int main()
{
{
public:
Type _data; A<int> ai(5);
A(Type data) : _data(data) { } ai.isBigger(7);
bool isBigger(Type data); //generic isBigger()
};
template <class Type> A<char*> as("hi");
bool A<Type>::isBigger(Type data) as.isBigger("bye");
{
return data > _data; //specific isBigger()
} }
template <>
bool A<char*>::isBigger(char *data)
{
return strcmp(data, _data) > 0;
}
19
++C
Template partial specialization
template <typename T1, typename T2>
class MyClass {
...
};
// partial specialization: same types parameters
template <typename T>
class MyClass<T,T> {
...
};
// partial specialization: second type is int
template <typename T>
class MyClass<T,int> {
...
};
// partial specialization: parameters are pointers
template <typename T1, typename T2>
class MyClass<T1*,T2*> {
...
20 };
++C
Template partial specialization
21
Generic stack, generic sort,
code reuse
A few examples of using templates for
generic programming
22
++C
String Stack
class StrStk {
public:
StrStk(): _first(nullptr) { };
~StrStk() { while (!isEmpty()) pop(); }
void push (string const& s ) { _first = new Node(s, _first); }
bool isEmpty() const { return _first == nullptr;}
const string& top () const { return _first->_value; }
void pop () { Node *n = _first; _first = _first->_next; delete n; }
private:
StrStk(StrStk const& rhs); // disallow copy from outside
StrStk& operator=(StrStk const& rhs);
struct Node {
string _value;
Node* _next;
Node(string const& v, Node* n) : _value(v), _next(n) { }
};
23 Node* _first;
++C
Int Stack
class IntStk {
public:
IntStk(): _first(nullptr) { };
~IntStk() { while (!isEmpty()) pop(); }
void push (int const& s ) { _first = new Node(s, _first); }
bool isEmpty() const { return _first == nullptr;}
const int& top () const { return _first->_value; }
void pop () { Node *n = _first; _first = _first->_next; delete n; }
private:
IntStk(IntStk const& rhs); // disallow copy from outside
IntStk& operator=(IntStk const& rhs);
struct Node {
int _value;
Node* _next;
Node(int const& v, Node* n) : _value(v), _next(n) { }
};
24 Node* _first;
++C
Generic Classes
private:
Stk(Stk const& rhs); // disallow copy from outside
Stk& operator=(Stk const& rhs);
struct Node {
T _value;
Node* _next;
Node(T const& v, Node* n) : _value(v), _next(n) { }
};
Node* _first;
26};