0% found this document useful (0 votes)
77 views

MATH49111/69111: Scientific Computing: 23rd October 2017

Operator overloading allows defining how operators like +, -, [], () work for user-defined classes. It is implemented by special member functions. Templates allow writing generic functions and classes that work for different data types by specifying a template type parameter. Function templates define a function that works for any type, while class templates define a class where member types are template parameters. Templates increase code reuse and flexibility.

Uploaded by

Pedro Luis Carro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
77 views

MATH49111/69111: Scientific Computing: 23rd October 2017

Operator overloading allows defining how operators like +, -, [], () work for user-defined classes. It is implemented by special member functions. Templates allow writing generic functions and classes that work for different data types by specifying a template type parameter. Function templates define a function that works for any type, while class templates define a class where member types are template parameters. Templates increase code reuse and flexibility.

Uploaded by

Pedro Luis Carro
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

MATH49111/69111: Scientific Computing

Lecture 9
23rd October 2017

Dr Chris Johnson
[email protected]
Lecture 9

. Operator overloading
. Templates
Operator overloading
We have seen examples already of operators acting on classes:
std::string s1("hello "), s2("world");
std::string s3 = s1 + s2; // + concatenates strings

std::vector<int> v(10);
v[0] = 5; // [] accesses elements

This is called operator overloading.

Operator overloading is achieved by special member functions:


class MyClass
{
double operator[](int i) // member function for [] operator
{
return ...; // implement operator behaviour
}
};
Operator overloading

Operator overloading can be used to define:


. mathematical operators +, -, * etc. for mathematical objects
(e.g. a Matrix class).
. relational operators <, > etc. to define an ordering
. subscript operators [] for container classes
. input and output operators >> and << for use with streams
(std::cout etc.)
. the function call operator () to give objects the syntax of
functions

For details, see example sheet 5 + answers, now online;


C++ Primer Chapter 14.
Operator overloading
Example: recall our Integrand base class, where we defined a pure
virtual function
virtual double Evaluate(double x) = 0;

We can instead overload operator() in Integrand:


virtual double operator()(double x) = 0;

and implement operator() in our derived class


virtual double operator()(double x)
{ /* return our integrand as function of x */ }

then call (references/pointers to) Integrand objects as functions:


double Integral(double a, double b, Integrand &i)
{
// Trapezium rule with one trapezium
return (b-a)*0.5*(i(a)+i(b));
}
Operator overloading
Example: recall our Integrand base class, where we defined a pure
virtual function
virtual double Evaluate(double x) = 0;

We can instead overload operator() in Integrand:


virtual double operator()(double x) = 0;

and implement operator() in our derived class


virtual double operator()(double x)
{ /* return our integrand as function of x */ }

then call (references/pointers to) Integrand objects as functions:


double Integral(double a, double b, Integrand &i)
{
// Trapezium rule with one trapezium
return (b-a)*0.5*(i(a)+i(b));
}
Templates

. Templates allow functions and classes to have type parameters.


. This is useful if we want to write code without specifying
exactly the type of objects it acts on.
. For example, std::vector has a template to specify the type
of object it contains:
std::vector<int> v(50);

. Template parameters are denoted by triangular brackets < >


. We can apply templates to functions, and to classes
Function templates

How can we implement a C++ function to bound a value x between


two limits a and b (with a @ b):

ˆx, a, b min ˆmax ˆx, a , b

double Bound(double x, double a, double b)


{
if (x<a) return a;
else if (x>b) return b;
return x;
}
Function templates

How can we implement a C++ function to bound a value x between


two limits a and b (with a @ b):

ˆx, a, b min ˆmax ˆx, a , b

Exactly the same function could be written with int…


int Bound(int x, int a, int b)
{
if (x<a) return a;
else if (x>b) return b;
return x;
}
Function templates

How can we implement a C++ function to bound a value x between


two limits a and b (with a @ b):

ˆx, a, b min ˆmax ˆx, a , b

…or with float:


float Bound(float x, float a, float b)
{
if (x<a) return a;
else if (x>b) return b;
return x;
}
Function templates

How can we implement a C++ function to bound a value x between


two limits a and b (with a @ b):

ˆx, a, b min ˆmax ˆx, a , b

We can define this function for all types with a template:


template <typename T>
T Bound(T x, T a, T b)
{
if (x<a) return a;
else if (x>b) return b;
return x;
}

The compiler deduces the type T from the type of the arguments
passed.
Function templates
#include <iostream>

template <typename T>


T Bound(T x, T a, T b)
{
if (x<a) return a;
else if (x>b) return b;
return x;
}

int main()
{
// works with double arguments
std::cout << Bound(1.5, 0.0, 1.0) << std::endl;
// works with int arguments
std::cout << Bound(-2, 0, 1) << std::endl;
// ambiguous template type; specify explicitly
std::cout << Bound<double>(1.5, 0, 1) << std::endl;
return 0;
}
Function templates
#include <iostream>

template <typename T>


T Recurrence(T coef1, T coef2)
{
T b=1.0/3.0, a=1.0, c;
for (int i=0; i<20; i++) {
c = coef1*b+coef2*a;
std::cout << a <<std::endl;
a=b; b=c;
}
}

int main()
{
Recurrence<float>(19.0/3.0, -2.0);
Recurrence<double>(19.0/3.0, -2.0);
Recurrence<float>(4.0/3.0, -1.0/3.0);
Recurrence<double>(4.0/3.0, -1.0/3.0);
return 0;
}
Class templates

C++ supports template parameters for classes, as well as functions.

Recall our Point2D class:


class Point2D
{
public:
void SetXY(double x_, double y_)
{
x = x_; y = y_;
}
double GetX() {return x;}
double GetY() {return y;}
private:
double x, y;
};
Class templates

C++ supports template parameters for classes, as well as functions.

We can generalise this to use any type for the coordinates:


template <typename T>
class Point2D
{
public:
void SetXY(T x_, T y_)
{
x = x_; y = y_;
}
T GetX() {return x;}
T GetY() {return y;}
private:
T x, y;
};
Class templates

We declare instances of our templated class with


Point2D<double> p1;
Point2D<int> p2;

in the same manner as vector.

Templates can be used for much more. See


. C++ Primer, Chapter 16
. Modern C++ Design (A. Alexandrescu) for more complex
usage (so-called template meta programming)

You might also like