• Keine Ergebnisse gefunden

Object-Oriented Programming for Scientific Computing

N/A
N/A
Protected

Academic year: 2021

Aktie "Object-Oriented Programming for Scientific Computing"

Copied!
40
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Object-Oriented Programming for Scientific Computing

Smart Pointers and Constness

Ole Klein

Interdisciplinary Center for Scientific Computing Heidelberg University

ole.klein@iwr.uni-heidelberg.de

28. April 2015

(2)

C++11 and Dynamic Memory Management

Smart Pointer

C++11 offers a number of so-called smart pointers that can help manage dynamic memory and in particular ensure the correct release of allocated memory.

There are three different types of smart pointers:

std::unique_ptr<T>

std::shared_ptr<T>

std::weak_ptr<T>

The template argumentTspecifies the type of object the smart pointer points to.

The C++11 smart pointers are defined in the header filememory.

(3)

• In the case ofunique_ptrs there is always exactly one smart pointer that owns the allocated data. If this pointer is destroyed (e.g. because the function in which it was defined exits or the destructor of the object to which it belongs is called), then the virtual memory is freed.

• Smart pointers and normal pointers (raw pointers) should not be mixed to avoid the risk of unauthorized access to already freed memory or double release of memory. Therefore, the allocation of memory must be placed directly in the constructor call ofunique_ptr.

• An assignment of a normal pointer to a smart pointer is not possible (but a transfer in the constructor is).

(4)

Example for

unique_ptr

# include< memory >

# include< i o s t r e a m >

s t r u c t b l u b {

v o i d d o S o m e t h i n g () {}

};

int m a i n () {

std :: u n i q u e _ p t r <int> t e s t (new int) ;

t e s t = new int; // not a l l o w e d : a s s i g n m e n t f r o m raw p o i n t e r int a ;

t e s t = & a ; // not a l l o w e d : a s s i g n m e n t f r o m raw p o i n t e r std :: u n i q u e _ p t r <int> t e s t 5 (& a ) ; // a l l o w e d but d a n g e r o u s

* t e s t = 2; // n o r m a l m e m o r y a c c e s s

std :: u n i q u e _ p t r <int> t e s t 2 ( t e s t . r e l e a s e () ) ; // m o v e to o t h e r p o i n t e r

t e s t = std :: m o v e ( t e s t 2 ) ; // a s s i g n m e n t o n l y u s i n g m o v e

(5)

Example for

unique_ptr

t e s t . s w a p ( t e s t 2 ) ; // e x c h a n g e w i t h o t h e r p o i n t e r

if ( t e s t == n u l l p t r ) // c o m p a r i s o n

std :: c o u t < < " t e s t is n u l l p t r " < < std :: e n d l ;

if (! t e s t 2 ) // t e s t for e x i s t e n c e

of o b j e c t

std :: c o u t < < " t e s t 2 is n u l l p t r " < < std :: e n d l ; std :: u n i q u e _ p t r <int[] > t e s t 3 (new int[ 3 2 ] ) ; // a r r a y

t e s t 3 [7] = 12; // a c c e s s to a r r a y

if ( t e s t 3 ) // a c c e s s to raw p o i n t e r

std :: c o u t < < " t e s t 3 is " < < t e s t 3 . get () < < std :: e n d l ;

t e s t 3 . r e s e t () ; // r e l e a s e of m e m o r y

if (! t e s t 3 )

std :: c o u t < < " t e s t 3 is n u l l p t r " < < std :: e n d l ;

std :: u n i q u e _ p t r < blub > t e s t 4 (new b l u b ) ; // a l l o c a t e o b j e c t test4 - > d o S o m e t h i n g () ; // use m e t h o d of o b j e c t std :: u n i q u e _ p t r < FILE , int(*) ( F I L E *) > f i l e P t r (

f o p e n (" b l u b . txt ", " w ") , f c l o s e ) ; // C r e a t e and c l o s e f i l e }

(6)

shared_ptr

shared_ptrs point to memory that is used concurrently.

• Severalshared_ptrs can point to the same memory location. The number of simultaneousshared_ptrs to the same resource is monitored with reference counting. The allocated memory is freed when the lastshared_ptrpointing to it disappears.

• Apart from that the functionality ofshared_ptris the same as that of

unique_ptr.

• When the firstshared_ptrto an object is created, a manager object is created that manages both the allocated resources and a variable that counts how many pointers point to the resources at any given moment.

• For each copy of ashared_ptrthe counter is incremented, and it is lowered each time ashared_ptris deleted or modified to point to a different location.

If the counter reaches zero, the resources are released.

(7)

• If several objects haveshared_ptrs pointing to each other, they can be kept alive artificially after their scope ends, because each object has at least one pointer in the circle pointing to it.

• In order to break such a circuit, the classweak_ptrhas been created.

• Aweak_ptris not a real pointer. It can not be dereferenced and no methods can be invoked on it.

• Aweak_ptronly observes a dynamically allocated resource and can be used to check if it still exists.

• If access to the resource is required, the methodlock()ofweak_ptrcan be used to generate ashared_ptrto the resource. This then ensures the existence of the resource as long it is used.

• The manager object of ashared_ptrhas another counter, the so-called weak counter, which in turn counts the generatedweak_ptrs. While the allocated resource is released when noshared_ptrpoints on it, the manager object is released when in addition noweak_ptrpoints to it.

(8)

shared_ptr

to

this

• Sometimes a pointer pointing atthisis needed. As one shouldn’t mix smart pointers and raw pointers, ashared_ptrtothismust be used.

• If this is realized byshared_ptr<T> blub(*this), then a new manager object will be created and the memory of the object is either not released or released to early.

• Instead, one derives the class from the template class

enable_shared_from_this<T>. A pointer tothisis then created with the methodshared_from_this:

s h a r e d _ p t r < T > b l u b = s h a r e d _ f r o m _ t h i s () ;

• During the creation of such a derived object in the constructor of a

shared_ptr, a weak_ptrto the object itself is stored within the object. The methodshared_from_thisgenerates ashared_ptrout of this storedweak_ptr.

(9)

Example for

shared_ptr

# include< memory >

# include< i o s t r e a m >

c l a s s B a s e : p u b l i c std :: e n a b l e _ s h a r e d _ f r o m _ t h i s < Base >

{

v o i d d o S o m e t h i n g () {

std :: s h a r e d _ p t r < Base > m y O b j = s h a r e d _ f r o m _ t h i s () ; }

};

c l a s s D e r i v e d : p u b l i c B a s e {};

int m a i n () {

std :: s h a r e d _ p t r <int> t e s t P t r (new int) , t e s t P t r 2 ; t e s t P t r 2 = t e s t P t r ; // i n c r e a s e s s h a r e d c o u n t

std :: c o u t < < t e s t P t r . u s e _ c o u n t () < < std :: e n d l ; // n u m b e r of s h a r e d _ p t r s

t e s t P t r . r e s e t () ; // d e c r e a s e s s h a r e d count , t e s t P t r is

(10)

Example for

shared_ptr

// w e a k p o i n t e r e x a m p l e

std :: w e a k _ p t r <int> w e a k P t r = t e s t P t r 2 ; // i n c r e a s e s w e a k c o u n t t e s t P t r = w e a k P t r . l o c k () ;

if ( t e s t P t r )

std :: c o u t < < " O b j e c t s t i l l e x i s t s " < < std :: e n d l ; if ( w e a k P t r . e x p i r e d () )

std :: c o u t < < " O b j e c t d o e s n ’ t e x i s t any m o r e " < < std :: e n d l ; std :: s h a r e d _ p t r <int> t e s t P t r 3 ( w e a k P t r ) ; // t h r o w s e x c e p t i o n if

o b j e c t has v a n i s h e d // C a s t i n g of s h a r e d p o i n t e r s

std :: s h a r e d _ p t r < Base > b a s e P t r (new D e r i v e d ) ; std :: s h a r e d _ p t r < Derived > d e r i v e d P t r ;

d e r i v e d P t r = std :: s t a t i c _ p o i n t e r _ c a s t < Derived >( b a s e P t r ) ; //

c r e a t e c a s t s m a r t p o i n t e r s h a r i n g o w n e r s h i p w i t h o r i g i n a l p o i n t e r

}

(11)

Constant Variables

• For constant variables the compiler ensures that the content is not changed during program execution.

• Constant variables must be initialized when they are defined.

• They can not be changed later on.

c o n s t int n u m E l e m e n t s = 1 0 0 ; // i n i t i a l i z a t i o n

n u m E l e m e n t s = 2 0 0 ; // not allowed , c o n s t

• Compared to the macros in C, constant variables are preferred, because they allow the strict type checking of the compiler.

(12)

Constant Values

Constant References

• References can be also defined as constant. The value pointed to by the reference cannot be changed (using the reference).

• Constant variables only allow constant references (since otherwise they might be changed using the reference).

int n u m N o d e s = 1 0 0 ; // v a r i a b l e

c o n s t int& nn = n u m N o d e s ; // v a r i a b l e c a n n o t be c a n g e d u s i n g nn

// but can be u s i n g n u m N o d e s c o n s t int n u m E l e m e n t s = 99; // i n i t i a l i z a t i o n

int& ne = n u m E l e m e n t s ; // not allowed , const - c o r r e c t n e s s // w o u l d n ’ t be g u a r a n t e e d a n y m o r e c o n s t int& n u m E l e m = n u m E l e m e n t s ; // a l l o w e d

• Constant references are a great way to pass a variable to a function without copying.

M a t r i x C l a s s & o p e r a t o r+=(c o n s t M a t r i x C l a s s & b ) ;

(13)

Constant Pointers

For pointers there are two different types of constness. For a pointer it may be forbidden

• to change the contents of the variable to which it points. This is expressed by writingconstbefore the type of the pointer:

c h a r s [ 1 7 ] ;

c o n s t c h a r* pc = s ; // p o i n t e r to c o n s t a n t pc [3] = ’ c ’; // error , c o n t e n t is c o n s t

++ pc ; // a l l o w e d

• to change the address stored in the pointer (such a pointer effectively acts as a reference). This is expressed by writingconstbetween the type of the pointer and the name of the pointer:

c h a r* c o n s t cp = s ; // c o n s t p o i n t e r

cp [3] = ’ c ’; // a l l o w e d

++ cp ; // error , p o i n t e r is c o n s t

(14)

Constant Values

Constant Pointers

• Of course there is also the combination of both (which corresponds to a constant reference):

c o n s t c h a r* c o n s t cpc = s ; // c o n s t p o i n t e r to c o n s t a n t

cpc [3] = ’ c ’; // error , c o n t e n t is c o n s t

++ cpc ; // error , p o i n t e r is c o n s t

(15)

Constant Objects

• Objects can also be defined as constant.

• The user assumes that the content of a constant object doesn’t change. This must be guaranteed by the implementation.

• Therefore, it isn’t allowed to call methods that could change the object.

• Functions which will not violate the constness are marked by the addition of the keywordconstafter the argument list.

• The keyword is part of the name. There can be aconstand a non-const

variant with the same argument list.

• Important: theconstmust also be added to the method definition outside of the class.

• For constant objects onlyconstmethods can be called.

(16)

Constant Values

# include< i o s t r e a m >

c l a s s X {

p u b l i c:

int b l u b () c o n s t {

r e t u r n 3;

}

int b l u b () {

r e t u r n 2;

} };

int m a i n () {

X a ;

c o n s t X & b = a ;

std :: c o u t < < a . b l u b () < < " " < < b . b l u b () < < std :: e n d l ; // p r o d u c e s the o u t p u t "2 3"

}

Of course the behavior used here for illustrative purposes is misleading and should not be used.

(17)

Example: Matrix Class

d o u b l e* M a t r i x C l a s s ::o p e r a t o r[](int i ) {

if (( i <0) ||( i >= n u m R o w s _ ) ) {

std :: c e r r < < " I l l e g a l row i n d e x " < < i ;

std :: c e r r < < " v a l i d r a n g e is (0: " < < n u m R o w s _ < < " ) ";

std :: c e r r < < std :: e n d l ; e x i t ( E X I T _ F A I L U R E ) ; }

r e t u r n a_ [ i ];

}

c o n s t d o u b l e* M a t r i x C l a s s ::o p e r a t o r[](int i ) c o n s t {

if (( i <0) ||( i >= n u m R o w s _ ) ) {

std :: c e r r < < " I l l e g a l row i n d e x " < < i ;

std :: c e r r < < " v a l i d r a n g e is (0: " < < n u m R o w s _ < < " ) ";

std :: c e r r < < std :: e n d l ; e x i t ( E X I T _ F A I L U R E ) ; }

(18)

Constant Values

Using this we may write:

M a t r i x C l a s s A (4 ,6 ,0.0) ; for (int i =0; i < A . R o w s () ;++ i )

A [ i ][ i ] = 2 . 0 ;

c o n s t M a t r i x C l a s s E (5 ,5 ,1.0) ; for (int i =0; i < E . R o w s () ;++ i )

std :: c o u t < < E [ i ][ i ] < < std :: e n d l ;

Returning a pointer to a constant will prevent the object being implicitly modified by the return value:

A [ 2 ] [ 3 ] = -1.0; // ok , no c o n s t a n t E [ 1 ] [ 1 ] = 0 . 0 ; // c o m p i l e r e r r o r

(19)

Physical and Logical Constness

When is a methodconst?

1 The object remains bitwise unchanged. That’s how the compiler sees it (that’s all it can check) and what it tries to ensure e.g. by treating all data members of aconstobject also as constants. This is also known as physical constness.

2 The object remains conceptually unchanged for the user of the class. This is referred to as a logical constness. But the compiler is unable to check the semantics.

(20)

Constant Values

Physical Constness and Pointers

• In our matrix class example with dynamic memory management, we have used a pointer of typedouble **to store the matrix.

• Making this pointer constant we obtain a pointer of typedouble ** const. This way it’s only forbidden to change the memory address which is stored in the pointer but not the entries in the matrix.

• The compiler doesn’t complain about the definition:

d o u b l e& M a t r i x C l a s s ::o p e r a t o r() (int i , int j ) c o n s t;

This therefore allows changing a constant object:

c o n s t M a t r i x C l a s s E (5 ,5 ,1.0) ; E (1 ,1) = 0 . 0 ;

• It is even allowed to change the entries within the class itself:

d o u b l e& M a t r i x C l a s s ::o p e r a t o r() (int i ,int j ) c o n s t {

a_ [ 0 ] [ 0 ] = 1 . 0 ; r e t u r n a_ [ i ][ j ];

}

(21)

Alternatives

• Using an STL container as in the first variant of the matrix class:

std :: vector < std :: vector <double> >

• In aconstobject this becomes aconst std::vector<std::vector<double> >.

• Defining the access function

d o u b l e& M a t r i x C l a s s ::o p e r a t o r() (int i , int j ) c o n s t;

results in an error message from the compiler:

m a t r i x . cc : In m e m b e r f u n c t i o n ’ d o u b l e &

M a t r i x C l a s s :: o p e r a t o r () ( int , int ) c o n s t ’:

m a t r i x . cc : 6 3 : e r r o r : i n v a l i d i n i t i a l i z a t i o n of r e f e r e n c e of t y p e ’ d o u b l e & ’ f r o m e x p r e s s i o n of t y p e ’ c o n s t d o u b l e ’

(22)

Constant Values

Alternatives (II)

• Returning entire vectors with:

std :: vector <double>& M a t r i x C l a s s ::o p e r a t o r[](int i ) c o n s t;

fails as well:

m a t r i x . cc : In m e m b e r f u n c t i o n ’ std :: vector < double ,

std :: a l l o c a t o r < double > >& M a t r i x C l a s s :: o p e r a t o r []( int ) c o n s t ’:

m a t r i x . cc : 8 7 : e r r o r : i n v a l i d i n i t i a l i z a t i o n of r e f e r e n c e of t y p e ’ std :: vector < double , std :: a l l o c a t o r < double > >& ’ f r o m e x p r e s s i o n of t y p e ’ c o n s t std :: vector < double ,

std :: a l l o c a t o r < double > > ’

Note: Using pointers it is easy to circumvent the compiler functionality for monitoring physical constness. Therefore it is appropriate to exercise caution when usingconstmethods for objects that use dynamically allocated memory.

(23)

Logical Constness and Caches

• Sometimes it is useful to store calculated values with high computational cost in order to save computing time when they are needed several times.

• We add the private variablesdouble norm_andbool normIsValid_to the matrix class and make sure thatnormIsValid_will always be initialized withfalsein the constructor.

(24)

Constant Values

Logical Constness and Caches

• Then it is possible to implement an infinity norm as follows:

d o u b l e M a t r i x C l a s s :: I n f i n i t y N o r m () {

if (! n o r m I s V a l i d _ ) {

n o r m _ = 0.;

for (int j = 0; j < n u m C o l s _ ; ++ j ) {

d o u b l e sum = 0.;

for (int i = 0; i < n u m R o w s _ ; ++ i ) sum += f a b s ( a_ [ i ][ j ]) ;

if ( sum > n o r m _ ) n o r m _ = sum ; }

n o r m I s V a l i d _ = t r u e; }

r e t u r n n o r m _ ; }

• This function also makes sense for a constant matrix and doesn’t semantically violate the constness.

(25)

Solution

• One defines both variables asmutable.

m u t a b l e b o o l n o r m I s V a l i d _ ; m u t a b l e d o u b l e n o r m _ ;

• Members that aremutable can also be modified inconstobjects.

• This should only be applied when it’s absolutely necessary and doesn’t change the logical constness of the object.

(26)

Constant Values

Friend

In some cases it may be necessary for other classes or functions to access the protected members of a class.

Example:Simply linked list

Nodecontains the data.

Listshould be able to change the data ofNode.

• The data ofNodeshould be private.

Listisfriend ofNodeand may therefore access private data.

(27)

Friend II

• Classes and free functions can befriendof another class.

• Such afriendmay access the private data of the class.

Examplefriendclass:

c l a s s L i s t ; c l a s s N o d e {

p r i v a t e:

N o d e * n e x t ; p u b l i c:

int v a l u e ;

f r i e n d c l a s s L i s t ; };

(28)

Constant Values

Friend II

• Classes and free functions can befriendof another class.

• Such afriendmay access the private data of the class.

Examplefriendfunction:

c l a s s M a t r i x C l a s s {

f r i e n d M a t r i x C l a s s i n v e r t (c o n s t M a t r i x C l a s s &) ; // ...

};

...

M a t r i x C l a s s A ( 1 0 ) ; ...

M a t r i x C l a s s inv = i n v e r t ( A ) ;

(29)

Friend III

• Almost everything that can be written as a class method can also be programmed as a freefriendfunction.

• All classes and functions which arefriendlogically belong to the class, as they build on its internal structure.

• Avoidfriend declarations. They open up encapsulation and raise the cost of maintenance.

(30)

Build Systems

Build Systems

• Complex projects consist of various programs and libraries.

• Each program / library consists of many files (header and source files).

• Build systems are created to make things easier when compiling.

Goal:

• A build system knows how to create the programs and libraries from the files.

• If a file is modified, the project should be updated.

• Typically not all files must be recompiled.

• Recompile as many files as necessary . . . and as few as possible.

(31)

Build Systems

• Complex projects consist of various programs and libraries.

• Each program / library consists of many files (header and source files).

• Build systems are created to make things easier when compiling.

Goal:

• A build system knows how to create the programs and libraries from the files.

• If a file is modified, the project should be updated.

• Typically not all files must be recompiled.

• Recompile as many files as necessary . . . and as few as possible.

(32)

Build Systems

Choice of Build Systems

There are several different systems with different ranges of functionality:

• make

• mk

• SCons

• ant

• jam

• Rant

• built-ins or plugins of the IDE

• . . .

Moreover, there are

meta-systems which generate input files for other systems:

• automake/autoconf

• cmake

• qmake

• mkmf

• . . .

(33)

Choice of Build Systems

There are several different systems with different ranges of functionality:

• make

• mk

• SCons

• ant

• jam

• Rant

• built-ins or plugins of the IDE

• . . .

Moreover, there are

meta-systems which generate input files for other systems:

• automake/autoconf

• cmake

• qmake

• mkmf

• . . .

(34)

Build Systems

Makefiles

• makeis a program that allows to translate only the files that have changed since the last compilation.

• AMakefiledescribes the files which belong to a project and how they are compiled and linked.

• Makefilerules are written in a functional language.

One describestargets, which depend onprerequisites.

targetsandprerequisitesnormally correspond to files.

For individualtargetsone creates rules that define how they are generated using thererequisites.

• Makefilerules are of the form

target - n a m e : p r e r e q u i s i t e s - l i s t build - r u l e

with the actual rule being indented with aTAB.

(35)

Easy Makefile Example

all : t e s t _ r a t i o n a l f a r e y f a r e y : f a r e y . o r a t i o n a l . o

g ++ f a r e y . o r a t i o n a l . o - o f a r e y t e s t _ r a t i o n a l : r a t i o n a l _ t e s t . o r a t i o n a l . o

g ++ r a t i o n a l _ t e s t . o r a t i o n a l . o - o t e s t _ r a t i o n a l r a t i o n a l _ t e s t . o : r a t i o n a l _ t e s t . cc r a t i o n a l . h

g ++ - c r a t i o n a l _ t e s t . cc r a t i o n a l . o : r a t i o n a l . cc r a t i o n a l . h

g ++ - c r a t i o n a l . cc f a r e y . o : f a r e y . cc r a t i o n a l . h

g ++ - c r a t i o n a l . cc

(36)

Build Systems

Advanced Makefile Example

# the c o m p i l e r we w a n t to use CXX = g ++

# s o m e m o r e v a r i a b l e s C P P S R C =$( w i l d c a r d *. cc ) O B J S =$( C P P S R C :. cc =. o ) A P P S = t e s t _ r a t i o n a l f a r e y

### b u i l d all a p p s all : $( A P P S )

# how to b u i l d the a p p s f a r e y : f a r e y . o r a t i o n a l . o

t e s t _ r a t i o n a l : r a t i o n a l _ t e s t . o r a t i o n a l . o

# how to c o m p i l e a p p s

%: %. o

$( CXX ) $? - o $@

# how to c o m p i l e o b j e c t f i l e s

%. o : %. cc

$( CXX ) $( C X X F L A G S ) - c - o $@ $<

makesupports variables.

Rules can be formulated generically for differenttargets,

. . . using several automatic variables.

GNU makehas several special extensions (e.g. wildcards).

GNU makehas several rules already built in.

makecan also directly clean up the created files

and automatically check the dependencies with the help of the compiler.

(37)

Advanced Makefile Example

# the c o m p i l e r we w a n t to use CXX = g ++

CC =$( CXX )

# s o m e m o r e v a r i a b l e s C P P S R C =$( w i l d c a r d *. cc ) O B J S =$( C P P S R C :. cc =. o ) A P P S = t e s t _ r a t i o n a l f a r e y

### b u i l d all a p p s all : $( A P P S )

# how to b u i l d the a p p s f a r e y : f a r e y . o r a t i o n a l . o

t e s t _ r a t i o n a l : r a t i o n a l _ t e s t . o r a t i o n a l . o

# we use i m p l i c i t c o m p i l a t i o n r u l e s

makesupports variables.

Rules can be formulated generically for differenttargets,

. . . using several automatic variables.

GNU makehas several special extensions (e.g. wildcards).

GNU makehas several rules already built in.

makecan also directly clean up the created files

and automatically check the dependencies with the help of the compiler.

(38)

Build Systems

Advanced Makefile Example

# the c o m p i l e r we w a n t to use CXX = g ++

CC =$( CXX )

# s o m e m o r e v a r i a b l e s C P P S R C =$( w i l d c a r d *. cc ) O B J S =$( C P P S R C :. cc =. o ) A P P S = t e s t _ r a t i o n a l f a r e y

### b u i l d all a p p s all : $( A P P S )

# how to b u i l d the a p p s f a r e y : f a r e y . o r a t i o n a l . o

t e s t _ r a t i o n a l : r a t i o n a l _ t e s t . o r a t i o n a l . o

# we use i m p l i c i t c o m p i l a t i o n r u l e s

### D e p e n d e n c i e s dep : . d e p e n d s

# i n c l u d e . d e p e n d s if f i l e e x i s t s - i n c l u d e . d e p e n d s

# how to c r e a t e . d e p e n d s . d e p e n d s : $( SRC )

$( CXX ) - MM $? > . d e p e n d s

### c l e a n u p c l e a n :

$( A P P S ) $( O B J S )

makesupports variables.

Rules can be formulated generically for differenttargets,

. . . using several automatic variables.

GNU makehas several special extensions (e.g. wildcards).

GNU makehas several rules already built in.

makecan also directly clean up the created files

and automatically check the dependencies with the help of the compiler.

(39)

Alternative: IDEs

• Integrated Development Environments (IDEs) combine the properties of an editor, a build system and a debugger

• e.g. Eclipse C/C++ Development Environment (http://www.eclipse.org/cdt)

• Eclipse is powerful and open source, but also very complex

(40)

Build Systems

Multiple Header Inclusion Prevention

• One can use macros to prevent the repeated inclusion of a header file.

• The content of the header file is put inside a conditional block:

# i f n d e f _ M Y S P E C I A L H E A D E R F I L E _

# d e f i n e _ M Y S P E C I A L H E A D E R F I L E _ // c o n t e n t of h e a d e r f i l e

# e n d i f

• The first inclusion of the header results in the definition of the macro and parsing of the content of the header file.

• Subsequent inclusions skip the content, since the macro is already defined.

Referenzen

ÄHNLICHE DOKUMENTE

replace_copy(b,e,out,v,v2) Create copy of all elements in range [b:e) re- placing elements which are equal to v with v2 , return iterator to end of copy.

• Traits can be used to specify types and values that depend on one or more template parameters. • Policies can be used to specify parts of algorithms as

Since the units are only used as a template parameter, this only affects the class type but does not require memory... Example: Numbers

This header also contains functions that provide a thread ID and the functionality to detach threads that afterwards run as a separate program (fork).. Mutual Exclusion The header

and no exercise group, because things are still being set up, but you are welcome to attend if you have questions about the lecture or exercises or something else to discuss.. E

~List (); // clean up the list and all nodes Node* first() const; // return a pointer to the first entry Node* next( const Node* n) const; // return a pointer to the node after n

Please modify your implementation again to obtain a doubly linked list: each element should also point to its predecessor.. What is

To understand why the size of empty classes (according to standard) is as observed, consider the following class!. struct