Motivation
• Following functionprints an array of
integer elements:
void printArray(int* array, int size)
{
for ( int i = 0; i < size; i++ )
cout << array[ i ] << “, ”;
}
3.
...Motivation
• What ifwe want to print an array of
characters?
void printArray(char* array,
int size)
{
for ( int i = 0; i < size; i++ )
cout << array[ i ] << “, ”;
}
4.
...Motivation
• What ifwe want to print an array of
doubles?
void printArray(double* array,
int size)
{
for ( int i = 0; i < size; i++ )
cout << array[ i ] << “, ”;
}
5.
...Motivation
• Now ifwe want to change the way function
prints the array. e.g. from
1, 2, 3, 4, 5
to
1 - 2 - 3 - 4 - 5
6.
...Motivation
• Now considerthe Array class that wraps
an array of integers
class Array {
int* pArray;
int size;
public:
…
};
7.
...Motivation
• What ifwe want to use an Array class that
wraps arrays of double?
class Array {
double* pArray;
int size;
public:
…
};
8.
...Motivation
• What ifwe want to use an Array class that
wraps arrays of boolean variables?
class Array {
bool* pArray;
int size;
public:
…
};
9.
...Motivation
• Now ifwe want to add a function sum to
Array class, we have to change all the
three classes
10.
Generic Programming
• Genericprogramming refers to programs
containing generic abstractions
• A generic program abstraction (function,
class) can be parameterized with a type
• Such abstractions can work with many
different types of data
Templates
• In C++generic programming is done using
templates
• Two kinds
– Function Templates
– Class Templates
• Compiler generates different type-specific
copies from a single template
13.
Function Templates
• Afunction template can be parameterized
to operate on different types of data
14.
Declaration
template< class T>
void funName( T x );
// OR
template< typename T >
void funName( T x );
// OR
template< class T, class U, … >
void funName( T x, U y, … );
15.
Example – FunctionTemplates
• Following function template prints an array
having almost any type of elements:
template< typename T >
void printArray( T* array, int size )
{
for ( int i = 0; i < size; i++ )
cout << array[ i ] << “, ”;
}
User-defined Specializations
• Atemplate may not handle all the types
successfully
• Explicit specializations need to be
provided for specific type(s)
21.
Example – UserSpecializations
template< typename T >
bool isEqual( T x, T y ) {
return ( x == y );
}
22.
… Example –User Specializations
int main {
isEqual( 5, 6 ); // OK
isEqual( 7.5, 7.5 ); // OK
isEqual( “abc”, “xyz” );
// Logical Error!
return 0;
}
23.
… Example –User Specializations
template< >
bool isEqual< const char* >(
const char* x, const char* y ) {
return ( strcmp( x, y ) == 0 );
}
24.
… Example –User Specializations
int main {
isEqual( 5, 6 );
// Target: general template
isEqual( 7.5, 7.5 );
// Target: general template
isEqual( “abc”, “xyz” );
// Target: user specialization
return 0;
}
25.
… Example –Function Template
#include <iostream>
using namespace std;
// Function template definition
template <typename T> T myMax(T x, T y) {
return (x > y) ? x : y;
}
int main() {
// Call myMax for int
cout << myMax<int>(3, 7) << endl;
// call myMax for double
cout << myMax<double>(3.0, 7.0) << endl;
// call myMax for char
cout << myMax<char>('g', 'e');
return 0;
}
26.
Class Templates
• Classtemplates like function
templates, are useful when a class
defines something that is
independent of the data type.
• It is useful for classes like
LinkedList, BinaryTree, Stack,
Queue, Array, etc.
27.
Example
#include <iostream>
using namespacestd;
// Defining class template
template <typename T>
class A {
public:
T x;
T y;
// Constructor
A(T val1, T val2) : x(val1), y(val2) {}
// Method to get values
void getValues() {
cout << x << " " << y;
}
};
28.
Example
int main() {
//Creating objects of A with
// different data types
A<int> intA(10, 20);
Geek<double> doubleA(3.14, 6.28);
// Access the templates values
intA.getValues();
cout << endl;
doubleA.getValues();
return 0;
}
29.
Example
#include <iostream>
using namespacestd;
// Defining class template with
// multiple type parameters
template <typename T1, typename T2, typename T3>
class A {
public:
T1 x;
T2 y;
T3 z;
// Constructor to initialization
A(T1 val1, T2 val2, T3 val3) :
x(val1), y(val2), z(val3) {}
// Method to get values
void getValues() {
cout << x << " " << y << " " << z;
}
};
30.
Example
int main() {
//Creating objects of A
// with different data types
A<int, double, string> intDoubleStringA(10,
3.14, "Hello");
A<char, float, bool> charFloatBoolA('A', 5.67f,
true);
intDoubleStringA.getValues();
cout << endl;
charFloatBoolA.getValues();
return 0;
}
Friend Functions
►In orderto access the member variables of the class,
function definition must be made a friend function:
class X{
private:
int a, b;
public:
…
friend void DoSomething(X obj);
}
►Now the function DoSomething can access data
members of class X
34.
Friend Functions
►Prototypes offriend
functions appear in the class
definition
►But friend functions are
NOT member functions
35.
Friend Functions
►Friend functionscan be placed anywhere in the
class without any effect
►Access specifiers don’t affect friend functions or
classes
class X{
...
private:
friend void DoSomething(X);
public:
friend void DoAnything(X);
...
};
36.
Friend Functions
►While thedefinition of the friend function
is:
void DoSomething(X obj){
obj.a = 3; // No
Error
obj.b = 4; // No
Error
…
}
►friend keyword is not given in definition
37.
Friend Functions
►If keywordfriend is used in the function
definition, it’s a syntax error
//Error…
friend void DoSomething(X obj){
…
}
38.
Friend Classes
•Similarly, oneclass can also be made
friend of another class:
class X{
friend class Y;
…
};
•Member functions of class Y can access
private data members of class X