C++ Advanced Tutorial - Lesson 3
Related Blog Items
- C++ Tutorial Part 2 - Advanced
- C++ Basics - Tutorial
- C++ Advanced Tutorial - Lesson 11
- C++ Advanced Tutorial - Lesson 8
- C++ Advanced Tutorial - Lesson 2
Please refer Lesson 2..
3. TEMPLATES
3.1 Function Template
3.2 Class Templates
3.3 The Power of Type Extensibility with Class Template
3.4 Non-Type Parameters in Class Template
3.5 Templates and Friends
3. TEMPLATES
3.1 Function Template
Suppose we want to write a function which receives two numbers and prints them out. It may either receive an int or a float or a char. If we use overloaded method, we have to create nine overloaded methods for the combination, such as:
void print(int a, int b) { cout << a << b; } void print(int a, float b) { cout << a << b; } void print(int a, char b) { cout << a << b; } void print(float a, int b) { cout << a << b; } void print(float a, float b) { cout << a << b; }
But the implementations in different overloaded methods are identical. There is another more compact way - using method template:
template < class T1, class T2 > // T1 & T2 are called "Type Parameter". void print(T1 a, T2 b) { cout << a << b; } Then, when the compiler sees a method call print(3.0, 'M') it will match T1 with 3.0 i.e. float, and T2 with 'M' i.e. char. Then it will generate a brand new method from the template: void print(float a, char b) { cout << a << b; }
and then compile it.
Keyword class here means any user-defined or built-in type.
Method template can also be overloaded, just like overloading normal methods.
You may have noticed that in the method body the type parameter “T1″ and “T2″ never appears.
3.2 Class Templates
Class templates are also called parameterized types. The principle of class template is the same as method template:
template < class T1, class T2 > // Before class definition! class Test { public: Test(T1, T2); void set(T1 a0, T2 b0); void print() const; private: T1 a; T2 b; }; template < class T1, class T2 > // Before each method! Test<T1, T2>::Test(T1 a0, T2 b0) // Class name is tied to the type parameters :a(a0), b(b0) {} template < class T1, class T2 > void Test<T1, T2>::set(T1 a0, T2 b0) { a = a0; b = b0; } template < class T1, class T2 > void Test<T1, T2>::print() const { cout << a << " " << b << endl; } int main() { Test<float, int> t1(5.0, 5); // When creating object Test<char, float> t2('X', 5.0); t1.print(); t2.print(); }
Suppose “Test” is the name of a class template with type parameter “X”. When you declare new object of class “Test” in the class definition of another class, always use the following format:
Test
When creating a new object, use the following format:
Test Class template enables you to write a class which suits all types. Because user-defined types (classes) can also use the same operators such as “=”, “= =”, “<<", ">>” “+”, “-” etc. as primitives, virtually any user-defined type can be used in any class template. In other words, when we are writing a template, virtually we shouldn’t pay any attention to whether the operand is a built-in type object or a class object.
Test3.3 The Power of Type Extensibility with Class Template
3.4 Non-Type Parameters in Class Template
For class templates, not only type can create different template classes, but also non-type parameters. Any parameter can be used. Because only memory size must be fixed at compile time, all other parameters or variables used in a program can be decided at run time, in real cases only memory size parameters are used as non-type parameters to create template methods. Non-type parameters can have default arguments.
template<class T, int size = 1> class Test{ private: T array[size]; public: Test(); void print() const; }; template<class T, int size> Test<T, size>::Test() { for(int i=0; i < size; i++) cin >> array[i]; } template<class T, int size> void Test<T, size>::print() const { for(int i=0; i < size; i++) cout << array[i] << endl; } int main() { Test<int, 3> a1; Test<float, 5> a2; a1.print(); a2.print(); }
The use non-type parameter to create template classes with different memory sizes reminds us of using dynamic memory allocation. To create array in a normal way requires you to determine the memory size when writing your class; by using non-type parameter you can let the client who uses your code decide it; by using dynamic memory allocation you can decide the memory size at run time. So the flexibility is different.
3.5 Templates and Friends
Inside a class template X that had been declared with
template < class T> class X { ... };
There are the following ways of friendship declaration:
1. friend void f1( ); f1( ) is a friend of all template classes.
2. friend void A::f1( ); method f1( ) of class A is a friend of all template classes.
3. friend void f1( X<T> & ); f1( X<float> & ) will be a friend of class X<float> only, and f1( X<int> & ) will be a friend of class X<int> only.
4. friend void C<T>::f1( X<T> & ); method C<float>::f1( X<float> & ) will be a friend of class X<float> only. "C" is the name of another class.
5. friend class Y; every method of class Y is a friend of all template classes.
6. friend class Y<T>; class Y<float> is a friend of class X<float> only.
Popularity: 23%
You need to log on to convert this article into PDF
Related Blog Items - C++ Tutorial Part 2 - Advanced
- C++ Basics - Tutorial
- C++ Advanced Tutorial - Lesson 11
- C++ Advanced Tutorial - Lesson 8
- C++ Advanced Tutorial - Lesson 2
Related Blog Items
- C++ Tutorial Part 2 - Advanced
- C++ Basics - Tutorial
- C++ Advanced Tutorial - Lesson 11
- C++ Advanced Tutorial - Lesson 8
- C++ Advanced Tutorial - Lesson 2
No Comments
No comments yet.