Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Stefan Lang
Interdisciplinary Center for Scientific Computing, University of Heidelberg
1 / 85
C++ f
ur Wissenschaftliches Rechnen I
1
2
3
4
5
6
7
8
9
10
11
Why C++?
Motivation
Concepts of C++
Basic Literature
Basic Techniques
The first Program
Compiling and Linking
Fundamental C++
Data Types
Control Flow
Functions
Pointer and References
Memory Management in C++
Abstract Data Types and Their Realisation in C++
Classes
Constructors and Destructors
Templates and Generic Programming
The Standard Template Library (STL)
Stefan Lang (IWR, Heidelberg)
2 / 85
C++ f
ur Wissenschaftliches Rechnen II
12
13
14
15
16
17
18
19
20
21
3 / 85
Why C++?
Motivation
Efficiency. . .
of program
of development
4 / 85
Why C++?
Motivation
low flexibility
bad maintainability
difficult to optimize
fast code
good optimization
C++
+
good maintainability
fast code
5 / 85
Why C++?
Concepts of C++
Concepts of C++
Inheritance and
6 / 85
Basic Literature
Literature
7 / 85
Basic Techniques
8 / 85
Hello World!
1
2
// include I/O-library
# include < iostream >
3
4
5
6
7
8
9
10
11
12
13
Compiler
Program
9 / 85
10 / 85
executable program.
The control of the process is performed via makefiles, that are however
11 / 85
include files
preprocessor
compiler
libraries
linker
program
11 / 85
Fundamental C++
Data Types
Integers
Large Integers
Characters
Floating point numbers 4
Byte
Floating point numbers 8
Byte
boolean values
int a = 2;
long a = 1e15;
char a = b;
float b = 3.14;
double c = 3.1415;
bool d = false;
12 / 85
Fundamental C++
Control Flow
Branches
if-branches:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
return 0;
15
16
13 / 85
Fundamental C++
Control Flow
Realisation of Loops
for loops,
while loops,
do..while loops.
1
2
3
4
5
6
int j = 5;
while ( j > 0)
{
std :: cout << " j : " << j << std :: endl ;
j - -;
}
8
9
10
11
12
13
14
return 0;
15
16
14 / 85
Fundamental C++
Functions
Functions
Functions
Functions are needed for encapsulation of program sections and can be called
when necessary.
In C++ their syntax always is
return - value function - name ( parameter1 , parameter2 , ..) ;
15 / 85
Fundamental C++
Functions
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// main function
int main ( int argc , char ** argv )
{
greet () ;
return 0;
}
16 / 85
Fundamental C++
Functions
// call-by-value
void swap_wrong ( int a , int b )
{
int tmp = a ;
a = b;
// does not work, a and b are local copies
b = tmp ;
// in the scope of the function
}
8
9
10
11
12
13
14
15
// call-by-reference
void swap_right ( int & a , int & b )
{
int tmp = a ; // a, b are reference parameters
a = b;
// That means changes to them are
b = tmp ;
// persistant after end of function call
}
17 / 85
Fundamental C++
Functions
1
2
3
4
// main function
int main ( int argc , char ** argv )
{
int a =5 , b =6;
// Output 5, 6
swap_wrong (a , b )
std :: cout << a << " , " << b << std :: endl ;
6
7
8
9
// Output 6, 5
swap_right (a , b )
std :: cout << a << " , " << b << std :: endl ;
10
11
12
13
return 0;
14
15
17 / 85
Address values can be stored in pointer variables. Pointer variables have the
syntax Typ* name, type ist the type of the object, on which the pointer points:
int * z = & x ; // z is a pointer variable
18 / 85
the value of the variable x can also be changed. Herefor exists the
(dereference operator *):
* z = 4711; // z is dereferenced, x has now the value 4711
Caution:
- With the dereference operator the pointer z is not changed. (z points still onto
the memory address of x).
- The symbol * denotes according to the context a dereference operator or a
pointer variable.
18 / 85
&
*intPtr = 6
dereference operator *
1
i
6
*
18 / 85
References
Besides pointer variables there are references.
References are internal pointers.
References can be considered as another name for a variable:
1
2
3
int x = 5;
int & y = x ; // another name for x
y = 4;
// means x = 4!
18 / 85
int i , j , *p , * q ;
int & s = i , & r = j ; // references have to be initialized
3
4
5
r = 2;
r = &j;
p = 2;
p = &j;
6
7
8
9
10
11
12
13
14
15
19 / 85
(Multi-dimensional) arrays are nothing else than pointer onto the first array entry:
1
int a [5];
2
3
4
5
a [0] = 3;
std :: cout << * a ; // output: 3 (= a[0])
std :: cout << & a ; // output: adress of a[0]
6
7
int a [3][20];
// 3 x 20 array
20 / 85
int ** p ;
int * p [10];
2
3
4
5
6
7
8
9
10
11
int * f ()
12
13
21 / 85
In C++ there are esentially thress memory segments where objects can be stored.
These are:
Memory segments in C++
1
The global memory segment. It stores all global variables and static
components of classes and compiled directly into the executable file.
The stack contains all instances of currently executed methods and functions
and their related local variables.
The heap provides memory, that can be allocated for dynamically allocated
objects.
22 / 85
Withe the code line intPtr = new int; memory space is allocated for nameless
object of type int and pointer to it is returned.
The construct new int
reserves space in the heap for an int value,
provides a pointer onto the allocated memory space.
23 / 85
Allocated memory space should be freed when an object is not necessary anymore.
This happens with the instruction delete:
int * intPtr ;
intPtr = new int ;
delete intPtr ;
// memory is freed
24 / 85
25 / 85
The following code clarifies the different life times of dynamic and static variables:
int foo () {
int * p = new int ;
* p = 5;
return p ;
}
void main ( void ) {
int * q = foo () ;
...
delete q ;
q = NULL ;
...
}
//
//
//
//
//
//
//
//
25 / 85
Classes
2
3
4
5
6
7
8
9
10
11
12
private :
double u , v ;
};
// ; is very important!
13
14
15
16
17
18
19
20
return 0;
21
22
26 / 85
Classes
From outside only methods and data in the public part can be accessed.
Implementation of methods can happen outside of the class.
27 / 85
Constructors
the class.
For initialisation the constructor is called.
There can exist several constructors (polymorphism!).
In certain cases the compiler generates default constructors.
28 / 85
Constructors
The class ComplexNumber with two constructors:
1
2
3
4
5
// default
6
7
8
9
10
11
12
13
14
private :
double u , v ;
};
29 / 85
Constructoren
1
2
3
4
5
6
a . print () ;
c = a + b;
8
9
// output: 3 + i * 4
// where defined ?
10
return 0;
11
12
};
30 / 85
Destructors
Dynamic generated objects can be destructed, if they are not necessary any
more.
Deletion of objects is handled by the destructor.
Destructors are especially to be (self)implemented, if the class contains
31 / 85
Overloading of Operators
can be self-implemented.
Classes, that implement the operator () are called Functors.
32 / 85
Templates
33 / 85
2
3
4
5
6
7
8
9
10
11
12
13
int main ()
{
int
i = 5, j = 6, k;
double l = 10.4 , m = 10.25 , n ;
14
15
16
17
18
return 0;
19
20
34 / 85
8
9
10
11
private :
T data [10];
};
12
13
14
15
16
17
18
19
20
21
35 / 85
28
29
30
31
32
33
34
35
// main program
# include < iostream >
int main ()
{
Array < int > c ; c . add (3 ,0) ; c . add (4 ,5) ; c . add (0 ,1) ;
std :: cout << c . at (5) << std :: endl ;
// output: 4
36
37
38
39
40
return 0;
41
42
36 / 85
Further on Templates
37 / 85
The STL
In C++ ther are many preexisting template container, that can be used for
implementation purposes. They are collected in a library, named STL.
The STL
is a collection of template classes and algorithms,
provides many container classes (class, that mananges a set of objects),
has therefore standardized user interfaces for the containers,
is contained in the C++ standard library.
38 / 85
The STL
Key-Value Container
Example: Maps, Multimaps
39 / 85
The STL
Optimizability by static
polymorphism
40 / 85
The STL
3
4
5
6
7
int main () {
// example usage of an STL vector
int result = 0;
std :: vector < int > x (100) ;
9
10
x . push_back (100) ;
11
12
13
14
15
// output: 5050
std :: cout << result << std :: endl ;
16
17
18
return 0;
19
20
41 / 85
The STL
42 / 85
The STL
4
5
6
7
8
int main ()
{
// example usage of an STL-map
std :: map < std :: string , int > y ;
10
11
12
13
14
15
16
17
18
19
return 0;
20
21
43 / 85
The STL
44 / 85
STL Algorithms
Algorithms
Examples:
Sorting
Searching
Copying
Reversing the ordering in the container
...
45 / 85
STL Algorithms
Algorithms
46 / 85
STL Algorithms
Algorithms
3
4
5
6
7
8
9
10
11
12
13
47 / 85
Inheritance in C++
Inheritance in C++
Inheritance
Data type passes its abstractions to other data types.
class GeomObject.
point no inheritance).
48 / 85
Inheritance in C++
Inheritance in C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
49 / 85
Inheritance in C++
In inheritance you have to take care of which members the derived class can
access different types of inheritance:
private inheritance:
all elements of the base class get private members of the derived class.
public inheritance:
public
members of the base class get public members of the derived class,
gets private.
private
50 / 85
Inheritance in C++
Private member of the base class stay always private (otherwise the
in anyway.
Ausweg: protected members can access onto derived classes.
50 / 85
Virtual Functions
Virtual Functions
Virtual Functions enable the hiding of methods of the base class by the derived
class:
1
2
3
class GeomObject
{
public :
5
6
7
};
8
9
10
11
12
13
14
15
double area ()
...
private :
{ return 0.5 * a * h ; }
16
double h , a ;
17
18
};
51 / 85
Virtual Functions
Virtual Functions
When Basis- and derived class members contain the same name Which method
is then called?
19
20
21
int main () {
GeomObject * geo ;
Triangle t ;
22
geo = & t ;
std :: cout << geo - > area () << std :: endl ; // ??
23
24
25
return 0;
26
27
};
Solution:
If specified otherwise the methods of the basis object (!).
By the keyword virtual the call is passed to the derived class.
Keyphrase Late Binding, i.e. mapping method name implementation
52 / 85
Virtual Functions
Dynamic Polymorphism
The techniqueu of late type-bindung with virtual functions has its own name:
Dynamic Polymorphism
Exact type determination during runtime.
Realisation by:
- Virtual functions (Function Lookup Table),
- Overloading of functions.
53 / 85
Virtual Functions
Dynamic Polymorphism
The techniqueu of late type-bindung with virtual functions has its own name:
Dynamic Polymorphism
Exact type determination during runtime.
Realisation by:
- Virtual functions (Function Lookup Table),
- Overloading of functions.
as well.
Example: List, that stores pointers onto GeomObjects Pointer can point onto a
Triangle-Objekt
53 / 85
Often virtual functions are not to be define meaningful inside the base class. Then
Declararation of function in the base clas as pure virtual:
Classes with one (or more) pure virtual functions are denoted abstract base
classes. They are pure interface specifications.
54 / 85
implementation.
55 / 85
Function
virtual double evaluate(double)
Midpointrule
Polynomial
56 / 85
6
5
4
p(x)
3
2
1
0
-1
-2
-2
-1.5
-1
-0.5
0
x
0.5
1.5
56 / 85
57 / 85
58 / 85
MIPOREGEL H
MIPOREGEL H
// clase midpointrule
c l a s s MidpointRule
{
public :
M i d p o i n t R u l e ( i n t c o u n t ) : n ( c o u n t ) {}
M i d p o i n t R u l e ( ) {};
// evaluate integral of function
d o u b l e e v a l u a t e I n t e g r a l ( F u n c t i o n& f , d o u b l e a , d o u b l e b ) c o n s t
{
double r e s = 0 . 0 ;
d o u b l e h = ( ba ) / ( 1 . 0 n ) ;
// interval length
// sum components of individual boxes
f o r ( i n t i =0; i<n ; ++i )
{
d o u b l e x = a + i h + 0.5 h ; // interval midpoint
r e s += h f . e v a l u a t e ( x ) ;
// function evaluation
}
return res ;
}
private :
int n;
};
#e n d i f
59 / 85
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
60 / 85
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#i n c l u d e <cmath>
// include base class / interface
#i n c l u d e f u n k t i o n . h
#i f n d e f
#d e f i n e
SINUS H
SINUS H
61 / 85
Polymorphismen
Dynamic Polymorphism
The completely normal polymorphism.
62 / 85
Polymorphismen
Static Polymorphism
Enables exchangeability during compile time only.
Allows all optimizations.
Longer compile times.
Reduces the overhead of the interface.
Stefan Lang (IWR, Heidelberg)
62 / 85
Polymorphismen
dynamic:
Virtual functions
Overloading of functions
Engine techniques
62 / 85
Polymorphismen
Dynamic Polymorphism
1
2
3
4
// base class
class Matrix {
virtual bool i s S y m m e t r i c P o s i t i v e D e f i n i t () ;
};
5
6
7
8
9
// symmetric matrices
class Sy mm e tr ic Ma t ri x : public Matrix {
virtual bool i s S y m m e t r i c P o s i t i v e D e f i n i t () { ... };
};
10
11
12
13
14
15
The request Is the matrix symmetric positive definite is passed from the base
63 / 85
Polymorphismen
Dynamic Polymorphism
1
2
3
4
// base class
class Matrix {
virtual bool i s S y m m e t r i c P o s i t i v e D e f i n i t () ;
};
5
6
7
8
9
// symmetric matrices
class Sy mm e tr ic Ma t ri x : public Matrix {
virtual bool i s S y m m e t r i c P o s i t i v e D e f i n i t () { ... };
};
10
11
12
13
14
15
The approach with virtual functions is in this case eventual not performant.
Way out: Static polymorphism (here: engine concept).
63 / 85
Polymorphismen
1
2
3
bool I s S y m m e t r i c P o s i t i v e D e f i n i t ()
{ return engineImp . i s S y m P o s i t i v e D e f i n i t e () ; }
5
6
7
};
8
9
10
11
12
13
14
15
16
17
class UpperTriangle {
bool i s S y m P o s i t i v e D e f i n i t e () { return false ; }
};
64 / 85
Polymorphismen
1
2
3
4
5
6
7
64 / 85
Polymorphismen
Matrix delegates most of the operations to the engine during compile time!
Dynamic polymorphism is substituted by static (templates).
Disadvantage: The base type (Matrix) has to contain all methods of all
subclasses.
The trick to avoid this is called Barton-Nackmann-Trick.
65 / 85
Polymorphismen
The Barton-Nackmann-Trick
Also known as Curiously Recursive Template Pattern:
1
2
3
5
6
7
bool I s S y m m e t r i c P o s i t i v e D e f i n i t ()
{ return asLeaf () . i s S y m P o s i t i v e D e f i n i t e () ; }
8
9
10
};
11
12
13
14
15
16
17
18
19
20
66 / 85
Polymorphismen
The Barton-Nackmann-Trick
1
2
3
4
5
6
7
8
9
66 / 85
Polymorphismen
The Barton-Nackmann-Trick
66 / 85
Motivation
67 / 85
Traits
Traits
Traits
Represent natural and additional properties of a template parameter.
Examples:
Meta informations for grids (Is grid conforming, adaptive, . . . )?
Type promotions.
68 / 85
Traits
Example:
std :: vector < int > a ;
std :: vector < complex < double > > b ;
std :: vector <??? > c = add (a , b ) ;
69 / 85
Traits
70 / 85
Traits
Example application:
std :: vector < int >
a (100 , 3) ;
std :: vector < double > b (100 , 3.1415) ;
c = add (a , b ) ; // is equivalent to
c = add (b , a ) ; // !
70 / 85
Traits
# define D E CL AR E _P RO MO T E (A ,B , C ) \
template < > struct Promotion <A ,B > { \
typedef C promoted_type ; \
}; \
template < > struct Promotion <B ,A > { \
typedef C promoted_type ; \
};
8
9
10
11
12
13
14
# undef D EC L AR E_ PR O MO TE
71 / 85
Traits
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
72 / 85
Traits
24
25
26
27
28
29
30
31
32
// main
int main ()
{
std :: cout << " min : " << min (88.9 , 99) << std :: endl ;
// output: 88.9
33
std :: cout << " min : " << min (4756 , a ) << std :: endl ;
// output: 97
34
35
36
return 0;
37
38
72 / 85
73 / 85
74 / 85
// fibonacci.cc:
// Compute fibonacci numbers at run- and compile time and compare
// the time used for it.
# include < iostream >
# include < cstdio >
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
75 / 85
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// main program
int main ()
{
// call of recursive Fibonacci
clock_t begin_rec = clock () ;
unsigned long result = F i b o n a c c i _S i m p l e (45) ;
clock_t end_rec = clock () ;
printf ( " Recursive Fib (45) = % ld computed in % lf secs .\ n " ,
result , ( double ) ( end_rec - begin_rec ) / CLOCKS _PER_SE C ) ;
75 / 85
48
49
50
51
52
53
54
return 0;
55
56
75 / 85
76 / 85
Template Specialisation
Template Specialisation
specialisation:
differences to the template pattern are implemented explicitly,
I.e. for data types that can be implemented run time and memory efficient.
77 / 85
Template Specialisation
Template Specialisation
78 / 85
Template Specialisation
Template Specialisation
Why do we need template specialisation?
Many algorithms (also non-templated ones) can be accelerated by specialisation
Example:
// dot-product
double dotproduct ( const double * a , const double * b , int N )
{
double result = 0.0;
for ( int i =0; i < N ; i ++)
result += a [ i ]* b [ i ];
return result ;
}
// specialization for small N (e.g. N=3) speeds up calculation
double dotproduct ( const double * a , const double * b , 3)
{
return a [0]* b [0] + a [1]* b [1] + a [2]* b [2];
}
79 / 85
Singletons
Singletons
Singleton Classes
secure maximal one instantiated object of a class
substitute global variables
can orccur in differend designs
80 / 85
Singletons
Singletons
80 / 85
Singletons
Singletons
80 / 85
Singletons
Singletons
Simplest Realization of a Singleton Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Singleton
{
public :
static Singleton & CreateI nstance ()
{
if ( mySingleton == NULL )
mySingleton = new Singleton singleton ;
return singleton ;
}
static void De leteInst ance ()
{
if ( mySingleton )
delete mySingleton ;
mySingleton = NULL ;
}
... // other public members
81 / 85
Singletons
Singletons
Simplest Realization of a Singleton Class
1
2
3
4
private :
static M yS in gl eton C l a s s * mySingleton ;
5
6
7
8
9
10
11
//
//
//
Singleton & operator =( const Singleton &) ; //
Singleton () {};
Singleton ( const Singleton &) ;
private constructor
prevent
copy-construction
prevent assignment
};
Singleton * Singleton :: mySingleton = NULL ;
12
13
14
15
16
...
// somewhere in the main program:
// create a Singleton instance and get a pointer to it
Singleton * aSingleton = Singleton :: Creat eInstanc e () ;
82 / 85
Exceptions
Exceptions
83 / 85
Exceptions
Exceptions
can be implemented.
83 / 85
Exceptions
Exceptions
1
2
3
try {
...
throw exception () ;
4
5
6
7
8
9
10
11
initialise () ;
...
//
//
//
//
instructions
raise error if it occurs
(Exception is an error class)
error can be raised in subfunctions
}
catch ( std :: exception & e )
{
...
// handle error
}
84 / 85
Advanced Literature
Advanced Literature
There exist many books concerning with proposed optimization possibilites by the
presented techniques (especially static polymorphism).
Literature for Scientific Computing with C++
Meta Programming)
85 / 85