Beruflich Dokumente
Kultur Dokumente
TO C/C++ LANGUAGE
Created by Tom Koudela
The file with block of functions is called module and it has .cpp
extension.
!sual include file extension is .h ".hpp for include files with class
definitions#.
!"!" #tru$ture o% t&e I)$lude F*le
$efinition of types
$efinitions of functions
Thus the name of any function may be arbitrary except of main and
0%011 keywords
"234 . main{} program-end program#
+" C Key/ord0
auto automatic variable . today unused
break breaks loops and switches
case denotes case of switches
char character type +5 si6e
const constant modifier of type
continue skip to next loop step
default denotes default case of switch
do begin of do7while loop
double real type with 85 si6e
else else statement of if-else
enum enumeration type
extern type modifier for global variables
float real type with ,5 si6e
for beginning of for loop
goto jump statement . almost never used
if beginning of if-else statement
int integer type with ,5 si6e
long integer type with ,5 si6e "85 on 9,bit#
or integer type modifier
"long long int . 85 on *:bit#
return return from function
short integer type with :5 si6e
signed default integer type modifier
sizeof determines si6e in bytes of variables
static type modifier for global module var
struct user defined structure composed from several other types
similar to 234 type-end type
switch beginning of switch statement
typedef definition of user types or aliases for built7in types
union similar to 234 common 7 almost unused
unsigned integer type modifier "suppression of sign#
void unknown type "pointer, parameter, return value#
volatile type modifier "system use#
while end statement of do-while loop
C++ keyword enhancement
class class type
public modifier of class data members
private modifier of class data members
protected modifier of class data members
friend modifier of class data members
this pointer to the actual instance of the object
operator function type modifier
inline function type modifier
try exception checking
catch exception catching
throw exception raise
template template of function or class
using using of declarations and%or definitions from the given
namespace or class
namesapce definition of namespace which prevents collisions of
identifiers and function%class names
1" O2erator0 a)d T&e*r 'r*or*ty
1. level (the highest)
( ) normal parenthesis
[ ] array index
-> access to class or struct members
class or struct are given by a pointer
. access to class or struct members
2. level
(type_name) type casting
& reference
* dereferencing "unary operator#
- minus "unary operator#
+ plus "unary operator#
! logical negation "unary operator#
++ increments operand by + or by si6e of type "pointers#
-- decrements operand by + or by si6e of type "pointers#
sizeof(var) returns si6e of variable var
sizeof(type_name) returns si6e of type type_name
3. level
* multiplication
/ division
% modulo of operands "rest of integer division#
4. level
+ addition
- subtraction
5. level
<< bit shift left
>> bit shift right
6. level
< or > less or greater then
<= or >= less or equal or greater or equal
7. level
== logical equal comparison
!= logical non7equal comparison
. level
& bitwise (;$
!. level
^ bitwise <=>
1". level
| bitwise =>
11. level
&& logical (;$
12. level
|| logical =>
13. level
? : ternary conditional operator "rarely used#
14. level
= assignment
-= += *= ... or any combination of logical, bitwise or
mathematical operator with =
performs operation given by the first operator with left and right
operands. The result is stored in the left operand. 2or example '
a += b is equivalent to a = a + b
a /= b is equivalent to a = a / b
15. #evel (lowest)
, operator of oblivion
3" Co)0ta)t0
The last hidden character '\0' of string constant is added by compiler. The
terminating character is necessary for the string length calculation and for
memory allocation. The character '\0' have to be the last character of all
strings.
\\ or \0x5c backslash
5lock of comments /* */
/* This sequence opens comment block
Body of the comment block
Following sequence closes comment block */
/*
/* This sequence opens comment block
Body of comment block
*/
The sequence above closes the comment block
*/ ???!!! undefined characters
4" Comme)t0
global module variables @ local at given module "file# but global to functions
defined in this module.
// global at one module
static long Counter;
or
long Counter;
=perator -> can be used in the case of access to the struct type via a
pointer "This approach is demonstrated in the concluding example of section
3.+#.
5"+" Ty2e Co)7er0*o)
enum answer {no=0, yes, maybe=5};
answer a;
double b;
int c;
long d;
c = int(a); // enum to int
c = int(b/d); // double to int
b = b/d; // implicit conversion to double
8" #tateme)t09 Blo$ o%
#tateme)t0
if (i%2) // if i is even
{
c = a+b;
i--; // decrement i (i=i-1)
}
else
{
c = a-b;
i *= 3; // i=i*3;
}
>esulting values for i@-: on input' a=5.0, b=2.0, c=3.0, i=15
>esulting values for i@+* on input' a=5.0, b=2.0, c=!.0, i=12
$witch $tatement switch( ) {}
switch (expression) {
case const_1:
statements or statement block
case const_2:
statements or statement block
default:
statements or statement block
}
The final statement is performed at the end of loop body for each
step.
E:am2le ;
double a[100];
for (long i=0; i < 100; i++)
{
a[i] = 0.0;
}
>esulting values'
a"0#=a"1#=a"2#=....=a"%%# = 0.0, i=100 or i is no& defined
long i, j, a[100];
for (i=0, j=1; i < 100; i++, j--)
{
a[i] = j;
}
>esulting values'
a"0#=1, a"1#=0, a"2#='1, ...., a"%%#='%(, i=100, )='%%
#oo% do while () ;
do
statement or statement block
while(expression);
Each function returns only one value, if no return value is required, the
void return type can be specified.
f the function does not return a value, either the void type can be specified or no
parameter type is specified.
<"+" Fu)$t*o) 'arameter0 -Ar(ume)t0.
n such the case, the compiler creates automatically local variables with given
name and type. Then it copies passed values into them and when function
finishes these variables are destroyed.
n case of overloading, several functions may have the same name, but they
have to have'
> different parameter types or
> number of parameters.
n such cases, changes of parameters performed in the function body modify their
real values Thus these changes take effect even outside of the given function.
t is necessary to count the last terminating character '\0' into the memory
allocation.
Thus the string consists of characters stored in the character array from the first
position to the first occurrence of '\0' including.
The si6e of allocated memory for string "array of char# can be greater then the
reported string length because terminating '\0' may occur at any position of
allocated array.
The s&ring leng&h is the number of characters from the array beginning to the first
occurrence of the terminating character '\0'.
$trings
Example'
char str[8];
str[0] = 'H'; str[1] = 'e'; str[2] = 'l';
str[3] = 'l'; str[4] = 'o'; str[5] = '\0';
D The length of str is -
D Einimum memory required
for "Hello" string storage
is 9 bytes.
D (dditional two bytes of
allocated memory are filled
with FG4F or not initiali6ed
Example of static array "static string#'
char *str = "Hello";
H e \0 o l l
0
x
0
4
0
0
5
1
0
x
0
4
0
0
5
5
0
x
0
4
0
0
5
4
0
x
0
4
0
0
5
3
0
x
0
4
0
0
5
2
0
x
0
4
0
0
5
8
0
x
0
4
0
0
5
7
0
x
0
4
0
0
5
6
0
x
0
4
0
0
5
9
Addresses of particular
memory bytes
emory co!te!t
str=0x040051,
*str = str[0] = 'H'
str+1=0x040052, str[1] = 'e'
str+2=0x040053, str[2] = 'l'
str+3=0x040054, str[3] = 'l'
str+4=0x040055, str[4] = 'o'
str+5=0x040056, str[5] = '\0'
(pplying arithmetics to the array pointer the value of pointer is changed and
it points to another array element.
abort(), (exit() ?)
char* mktmp(char *)
rand()
!@"+ ,at&"& Fu)$t*o)0
Prototypes of these functions are the same except of the first parameter.
2or the file %=, the first parameter is pointer to opened file.
The structure FILE contains an actual position in the opened file from%to
which the data are read%written. The initial position is set to the beginning or
end of file by function fopen() depending on its parameters.
0hanging position where the data are read or written is performed by the
function fseek().
E:am2le o% %*le o2erat*o)0;
FILE *in, *out, *iof, *oldf;
char fname[] = "EXAM/DAMAGE/dam1.in";
// opening text file for reading
in = fopen(fname, "rt");
// opening binary file for writing
out = fopen("input.dat", "wb");
// opening file for reading/writing
iof = fopen("input.dat", "r+");
// opening text file for writing, data will be appended
oldf = fopen("input.dat", "at");
fprintf(oldf, "My data\n"); // writing of string
fflush(oldf); // flushing buffered data
fclose(oldf); // closing file
fclose(in); fclose(out); fclose(iof); // closing files
-ormatted 'n%(t
(s/f)scanf(src, char *fmt, arg_1, arg_2, ...);
src is either pointer to structure FILE (FILE *)opened for reading or pointer to
source string "char *#
arg_i is a pointers to variable where the required data will be stored "t must have
the sufficient si6e to hold read data . by default, it is not chec&ed by the com'iler#
2or each call of fscanf is the internal file position shifted by the number of bytes
read. The position is stored in the structure 2)E which is given by src.
2or each call of sscanf, the internal string position cannot be remembered and thus
the next call of sscanf starts scanning of the string src from the string beginning
again.
-ormatted /(t%(t
(s/f)printf(src, char *fmt, arg_1, arg_2, ...);
src is either pointer to structure FILE "FILE *# opened for writing or pointer to
source string "char*#
2or each call of fscanf is the internal file position shifted by the number of
bytes read. The position is stored in the structure 2)E which is given by src.
2or each call of sscanf, the internal string position cannot be remembered and
thus the next call of sscanf starts scanning of the string src from the string
beginning again.
The pointer src must have enou(h memory allocated in order to store all output
variables.
-ormat $tring 0escri%tion
The format string may contain arbitrary sequence of characters except of % which
have a special meaning.
f a string literal is used for the format string than the %, \ and " characters cannot
be used.
" opens%closes string literal, quotas " inside a string literal can be written by \"
percent character at the output has to be denoted by %% in the format string or string
literal.
scanf functions process the % format sequence and they also try to read all
sequences of characters written in the format string which do not belong to %
format.
2ormat of printed%scanned variable is represented by % followed by format
specifiers and switches. The following specifiers are often used '
%d for integer
%s for string
%c for character
%p for pointer
0lass data are called da&a members or class a&&ribu&es and class
functions are called me&hods.
There are two special kinds of methods which are called cons&ruc&ors
and des&ruc&ors.
Each class has defined pointer this implicitly which references to the
currently used instance of the class.
The pointer this is a hidden argument for each method and it allows
for access to data members and methods.
The definition of methods is the same as the definition of a classical 0 function but
the method name is decorated by class name followed by '' operator
ret_type class_name::method_name(par_list){method body}
static . declarations with the static specifier declares that the given
attribute%method will be created independently on the instances of
the given class. &tatic attribute has only one instance for the given
class ty'e. &tatic attributes%methods may be accessed%called even
though the given class has no instance.
Examples of friend declaration'
class node
{ double x,z; // private members accessible for the following friends
friend int search(); // global function search() is a friend
friend elem::length(); // method length of elem class is a friend
friend topology; // class topology is a friend
};
Example of static declaration'
class node
{ // private members contained in every class instance
double x,z;
// Private static data member is stored separately only once for
// the given class. In this case, it contains a counter of instances
// of the class node.
static int ninst;
public :
node() { x = z = 0.0; ninst++;}; // default constructor
~node() { ninst--; }; // destructor
// static method allows for access to the static data member
static int get_ninst() { return ninst; };
};
. . .
int n = node::get_ninst(); // call of the static method
4ood 5rogramming 5ractice
0onstructors are methods with the same name as their class type.
$estructors are methods with same name as their class type preceded by ~.
0lasses can have several constructors "overloaded# which differ with a type of
parameters but only one destructor.
0onstructors of all data members are called before the constructor body is
performed.
The co*, cons&ruc&or is defined with one parameter which is of the given class
type passed by reference.
The copy constructor should copy data members from the object of constructor
argument into the corresponding data members of the current instance.
f the user do not specify a copy constructor and compiler finds that should be
called, it automatically creates one by the cons&ruc&or s,n&hesis . so called
shallo/ co*, cons&ruc&or,
B!T it does not allocate any dynamically allocated attributes in the class. t
only co'ies 'ointer values )addresses* not their content + "source of program
crashes in the case of automatic call of destructor for this object#
f the copy constructors are used and some class attributes are allocated
dynamically, the programmer E!&T implement own copy constructor which
performs dee* co*, of the object and takes care about correct dynamic memory
allocation and copying of the memory content.
$estructors are called each time the variable is removed. That means in the
case of delete call "controlled by programmer#,
0reation of one object from the other objects is called ob)ec& com*osi&ion
class matrix
{
public:
long m, n; // m number of rows, n number of columns
double *a; // array of matrix elements
matrix (long i, long j); // user defined constructor
void init(matrix &b); // initializes object from b
void print(FILE *out); // prints the matrix to out
double &get(long i, long j); // returns matrix element i-th,j-th
};
class element
{
public:
long *nodes; // array of node numbers
long nnod; // number of nodes on element
long nndof; // number of degrees of freedom (dofs) in one node
matrix stiffmat; // stiffness matrix
element(); // default constructor
};
0nheri&ance consists in cloning of an existing class%classes and modifying of
the class content or addition of new members and methods.
class element
{
public:
long *nodes
long nnod;
long nndof;
matrix stiffmat;
element();
// assemble stiffness matrix
void assemble_stiffmat(){ printf("Element stiffmat\n"); };
};
class beam : public element
{
public:
vector memfrc; // vector of member forces
beam(); // default constructor
// assemble stiffness matrix
void assemble_stiffmat(){ printf("Beam stiffmat\n"); };
void comp_memfrc(vector &r); // compute member forces
};
n the previous example'
The class beam inherits all data members and all methods from the base class
element except of constructors, destructors and the assignment operator =.
The keyword public in the inheritance syntax provides that all inherited data and
methods remain in their original access mode specified in the base class.
The private specification in the inheritance syntax changes the access mode for all
inherited data to private.
The protected specification in the inheritance syntax changes the access mode of
inherited public and protected data to protected while the inherited private data
remains in the private mode.
The new data member memfrc was added and new method comp_memfrc was
added for the member forces computation.
Public or protected inherited data members can be accessed in the child class methods
by the standard . or > operators.
6emory layo(t o* the o+7ects
element
beam
5ase class
$erived class
4
x
4
,
4
4
-
+
4
x
4
,
4
4
-
3
4
x
4
,
4
4
-
-
4
x
4
,
4
4
-
$
Program memory
4
x
4
,
4
4
J
+
4
x
4
,
4
4
9
3
nodes nndof
(ddresses of
particular
memory bytes
nherited data members ;ew data member
. . .
nnod stiffmat
element
::nodes
element
::nndof
element
::nnod
element::stiffmat memfrc
D
$erived class is a &,*e of base class. 2rom this point of view, the
object%pointer%reference of type of derived class can be used instead of base class
object%pointer%reference. 0onversion of object type of derived class to the base
class is called u*ca&sing
Example of upcasting'
#include "element.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
// base class pointer corresponds to the original definition
elems[i] = new element;
if (te[i] == 'b')
// pointer to the derived class CAN replace the original type
elems[i] = new beam; // upcasting is performed
}
// compute stiffness matrix for all elements
for (long i=0; i<ne; i++)
// method assemble_stiffmat is inherited
elems[i]->assemble_stiffmat();
return 0;
}
'nheritance 3 constr(ctor and destr(ctor iss(es
D
The main issue is the order of 'ro'er constructor calls which influences the
correct object creation.
D
f the programmer do not care about it, the compiler performs constructor
synthesis from the default constructors. The default order of constructor calls is
defined as follows'
> constructor of the base class
> constructor of the class members in the order given by the class definition
> constructor of the derived class
D
The order of the constructor calls and their type can be prescribed in the
cons&ruc&or ini&iali1er lis&.
D
f the constructor initiali6er list is incomplete, the compiler calls the default
constructors for the missing ones.
D
The destructors are called in the reverse order than the constructor were called.
Example of constructor initiali6er list'
class element{
// The definition of the class element is the same as
// in the example of constructors and destructors
...
...
};
class beam : public element{
public:
double a; // cross-section area
vector memfrc; // vector of member forces
// user defined default constructor initializes element attributes
// by explicit call of user defined constructor element::element(long)
// and also explicit call of beam attribute memfrc by user defined
// constructor vector::vector(long)
beam() : element(2), memfrc(6) { a = 0.0; }
// user defined constructor initializes element attributes
// by explicit call of user defined constructor element::element(long)
// default constructor vector::vector is called for memfrc attribute by
// compiler because nothing else is specified in the initializer list
beam(double area) : element(2) { a = area; }
// destructor
~beam(){};
};
Example of the order of constructor and destructor calls'
element::element()
matrix::matrix()
=rder of calls
matrix::~matrix()
element::element()
vector::vector()
element::~element()
matrix::~matrix()
vector::~vector()
element::~element()
matrix::matrix()
beam::beam()
beam::~beam()
element *e;
beam *b;
e = new element;
delete e;
b = new beam;
delete b;
e
e->stiffmat
b->stiffmat
b
b->memfrc
e
e->stiffmat
b->memfrc
b
b->stiffmat
b
b
&ource of calls
6(lti%le inheritance
D
0lass can be derived from the multiple base classes @ mul&i*le inheri&ance
Example'
class class_name : base_1, base_2 { . . . };
Example of non7virtual multiple inheritance'
class Base {public: short x;};
class DerA : Base {public: short a;};
class DerB : Base {public: short b;};
class DerAB : DerA, DerB {public: int c;};
DerivedAB z;
z.DerA::x = 5;
z.DerB::x = 4;
Base Base
DerB DerA
DerAB
DerAB::c DerA::a DerB::b Base::x Base::x Eemory content
4
x
4
,
4
4
-
+
4
x
4
,
4
4
-
-
4
x
4
,
4
4
-
,
4
x
4
,
4
4
-
*
4
x
4
,
4
4
-
:
4
x
4
,
4
4
-
8
4
x
4
,
4
4
-
J
4
x
4
,
4
4
-
9
4
x
4
,
4
4
-
3
4
x
4
,
4
4
-
E
4
x
4
,
4
4
-
$
4
x
4
,
4
4
-
0
4
x
4
,
4
4
9
5
4
x
4
,
4
4
-
(
(ddresses of particular
memory bytes
6
8irt(al inheritance
D
Eultiple inheritance can cause problems with multiple inherited members from
the common base class. These problems can be avoided by using of vir&ual
inheri&ance which provides that each member of the common base class is
contained only once in the derived class.
Example of virtual multiple inheritance'
class Base {public: short x;};
class DerA : virtual Base {public: short a;};
class DerB : virtual Base {public: short b;};
class DerAB : DerA, DerB {public: int c;};
DerivedAB z;
z.x = 5;
Base Base
DerB DerA
DerAB
DerAB::c DerA::aDerB::b Base::x
6
Eemory content
4
x
4
,
4
4
-
+
4
x
4
,
4
4
-
-
4
x
4
,
4
4
-
,
4
x
4
,
4
4
-
*
4
x
4
,
4
4
-
:
4
x
4
,
4
4
-
8
4
x
4
,
4
4
-
J
4
x
4
,
4
4
-
9
4
x
4
,
4
4
-
3
4
x
4
,
4
4
-
$
4
x
4
,
4
4
-
0
4
x
4
,
4
4
9
5
4
x
4
,
4
4
-
(
(ddresses of particular
memory bytes
!!"3 'olymor2&*0m
D
Polymorphism solves another issue which is connected with the inheritance. n the
upcasting example, one excepts naturally that for the eleminit(2, "eb") call, the
output should be following '
Element stiffmat
5eam stiffmat
5!T in reality the output will be'
Element stiffmat
Element stiffmat
The problem is that the compiler used earl, binding for assemble_stiffmat.
Early binding means that the compiler decided at compile time that
assemble_stiffmat from the original type of elems will be called.
D
The type of upcasted dynamically allocated objects is not known at compile time and
thus the la&e binding has to be used for the intended program behavior. The late
binding for methods can be enforced by the keyword virtual which precedes
returning type of the method in the class definition.
virtual ret_type method_name(par_list);
Example of virtual methods'
class element{
public:
long *nodes
long nnod;
long nndof;
matrix stiffmat;
element() { nodes = NULL; }
element(long nn) { nnod = nn; nodes = new long[nn]; }
~element(){ delete [] nodes; }
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Element stiffmat\n"); };
};
class beam : public element{
public:
vector memfrc; // vector of member forces
beam() : element(2), memfrc(6) { }; // default constructor
~beam() { }; // destructor
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Beam stiffmat\n"); };
void comp_memfrc(vector &r); // compute member forces
};
Example of virtual methods 7 continuation'
#include "element.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
elems[i] = new element;
if (te[i] == 'b')
// upcasting with late binding is performed
elems[i] = new beam;
}
// compute stiffness matrix for all elements
for (long i=0; i<ne; i++){
// method assemble_stiffmat is inherited,
// late binding is performed due to virtual keyword
elems[i]->assemble_stiffmat();
}
return 0;
}
2or the call eleminit(2, "eb"), the output will be following'
Element stiffmat
Beam stiffmat
5olymor%hism 9 r(les *or virt(al methods
D
The virtual modifier can be used for methods or destructors
D
0onstructors, static methods and friend functions must not be virtual.
D
f the method is virtual in a base class then the method must be virtual also in
a derived class.
D
5ase classes contain methods which cannot be implemented because of their
excessive abstraction and implementation of such methods is performed in
the derived classes. n such the case, the method can be declared as a *ure
vir&ual me&hod and the class containing at least one pure virtual method is
called abs&rac& class. The pure virtual method can be specified as follows'
virtual ret_type method_name(par_list) = 0;
D
The pure virtual method cannot be called and an instance of abstract class
cannot be created.
D
>eferences or pointers to abstract classes can be declared.
Example of virtual destructors . part '
// class definitions used in the example of virtual methods
#include "element.h"
#include "beam.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
elems[i] = new element;
if (te[i] == 'b')
// upcasting with early binding of destructor is performed
elems[i] = new beam;
}
... // execution of the main code of eleminit(int, char*)
for (long i=0; i<ne; i++){
// destructor of element and beam are not virtual and it leads to
// early binding -> destructor of vector memfrc is not called and
// memfrc memory is not released -> memory leak
}
delete [] elem;
return 0;
}
delete elems[i]; // destroy used elements
Example of virtual destructors . part '
=rder of calls
matrix::~matrix()
element::~element()
delete elem[i];
elem[i]->stiffmat
elem[i]
&ource of calls
nnod, nndof
nodes
stiffmat
nodes
memfrc
matrix::m
matrix::n
matrix::a
nodes[0]
nodes[1]
vector::n
vector::a
vector::real[0]
vector::real[5]
vector::real[1]
vector::real[2]
vector::real[4]
vector::real[3]
Memory leak
due to early
binding of
destructor
Explicit
memory
deallocation
by delete
Explicit
memory
deallocation
by delete
Example of virtual destructors . part '
class element{
public:
long *nodes
long nnod;
long nndof;
matrix stiffmat;
element() { nodes = NULL; }
element(long nn) { nnod = nn; nodes = new long[nn]; }
~element(){ delete [] nodes; } // virtual destructor
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Element stiffmat\n"); };
};
class beam : public element{
public:
vector memfrc; // vector of member forces
double *load; // uniform load
beam() : element(2), memfrc(6) {load = NULL;} // default constructor
~beam() { delete [] load; }; // virtual destructor
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Beam stiffmat\n"); };
void comp_memfrc(vector &r); // compute member forces
};
virtual
virtual
Example of virtual destructors . part H'
// class definitions used in the example of virtual methods
#include "element.h"
#include "beam.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
elems[i] = new element;
if (te[i] == 'b')
// upcasting with late binding of destructor is performed
elems[i] = new beam;
}
...
for (long i=0; i<ne; i++){
// destructor of element and beam ARE virtual and it leads to
// LATE binding -> destructor of beam is called -> destructor of
// vector memfrc is called consequently and memory of
// beam vector memfrc is RELEASED
}
delete [] elem; return 0;
}
delete elems[i]; // destroy used elements
Example of virtual destructors . part H'
=rder of calls
matrix::~matrix()
element::~element()
delete elem[i];
elem[i]->stiffmat
elem[i]
&ource of calls
nnod, nndof
nodes
stiffmat
nodes
memfrc
matrix::m
matrix::n
matrix::a
nodes[0]
nodes[1]
vector::n
vector::a
Explicit
memory
deallocation
by delete
vector::real[0]
vector::real[5]
vector::real[1]
vector::real[2]
vector::real[4]
vector::real[3]
Correct
explicit
memory
deallocation
by delete
due to late
binding of
destructor
beam::~beam() elem[i]
Explicit
memory
deallocation
by delete
vector::~vector() elem[i].memfrc
'm%lementation o* virt(al methods in C++
D
Each class containing at least one virtual method has automatically generated so
called vir&ual me&hod &able "HET or HT(5)E# which stores addresses of the
virtual methods.
D
The address "pointer# of HET is stored secretly into each instance of the given
class. The pointer to HET is often called HP=;TE>. Thus the si6e of each
class containing virtual methods is given by si6es of the attributes plus si6e of
HP=;TE>.
D
Hirtual methods are not called directly by their addresses but indirect calls via
V$T are performed. 0ompiler knows at compile time that the name of the
virtual method will be stored on certain position in HET.
D
0orrect virtual methods are called even thou(h the u'catin( to the base class is
performed due to the indirect call using HET. This behavior is allowed because
of HP=;TE> which is not influenced by the upcasting and remains constant.
nndof
nodes
stiffmat
memfrc
nnod
nndof
nodes
stiffmat
nnod
VPOINTER VPOINTER
elems[0] elems[1]
(rray elems
=bjects
&beam::
assamble_stiffmat()
&element::
assamble_stiffmat()
HT(5)Es
!+" O2erator o7erload*)(
The standard set of 011 operators can be overloaded similarly to the function
overloading.
#unction call operator (), [], =, static t$pecast operator (type) can be
overloaded as non7static methods only.
new and delete operators can be overload as static methods or ordinary functions.
0onstants in 011 are much more significant than in 0. n 0 language, the keyword
const just represents variable which cannot be changed and for which a memory
is always reserved. !nfortunately, this representation does not allows for usage of
consts in ranges of arrays in 0. The 011 allows for that for built in types but not
for user defined types.
const int size=20;
char buff[size]; // error in C, but not in C++
The consts should replace constants defined by preprocessor directive #define
in 011 because type checking is performed on consts.
The keypoint for usage of consts in array definitions is whether the const has
allocated memory for storage. f the memory allocation is necessary, than it cannot
be used in arrays definitions 5!T it still behaves like a constant i.e. the content of
the variable cannot be changed. The memory is allocated if'
1)extern modifier is used "default linkage of constants is static#
:# aggregated constants "struct or class type#
*# pointer to const is required "memory has to be reserved#
The only exception from the type checking is string literal where the assignment of
pointer to the array of constant characters is permitted to the pointer to non7constant
character.
char* str; // ordinary pointer to the character type
str = "Hello"; // str refers to the 'H' in the string Hello
The const specifier is also used for function arguments where it denotes that the
function does not modify their value inside function body. (rgument type of pointer
to a constant or constant reference are the most common used cases.
char* f(const char *str); // str[i] = 'a'; cannot be used within f()
char* g(const matrix &b); // b.get(i,j)=5.0; cannot be used within g()
=rdinary constants defined inside a class corresponds rather to 0 definition. 2or each
instance of the class, the memory is reserved for each const and all constants have
to be initiali6ed in the constructor initiali6er list. (fter initiali6ation, the value of the
constant remains the same during all existence of the instance. Thus the value of class
constants is set at run&ime.
class vector{
public:
const long n;
double *a;
vector(long size) : n(size) {a = new double[n];};
};
nstance of class can be defined to be constant also. n the case of constant object,
ordinary methods cannot be called but only cons&an& me&hod. 0ompiler checks each
call of method whether it is constant and it also checks that the data attributes are not
changed in the definition of the constant method.
class vector{
public:
static const double pi=3.14159265;
const long n;
double *a;
vector(long size) : n(size) {a = new double[n];};
vector(long size, double *v) : n(size) {a = v;};
double angle_degrees (const vector &v) const; // constant method
};
const double[2] e = {1.0, 0.0};
const vector a(2, (double*)e);
vector b(2); b.a[0]=1.0; b.a[1]=1.0;
double phi = a.angle_degrees(b);
phi = b.angle_degrees(a); // this line is valid even if angle_degrees
// would not be constant method
(ll temporary objects are assumed to be constant "temporary objects are created by
passing arguments by value and returning objects by values from the methods#.
!3" Name02a$e0
2ames*aces help to solve problems with conflicts of type or variable names in the
large projects or in case of merging two independent projects together. =ne
namespace can involve several class definitions, several variables declarations or
another namespaces. The syntax of the namespace is like follows'
namespace ns_name {}
Example of namespace definition'
namespace MatVecCalc{
class vector{ public:
long n;
double *a;
double norm();
double dotprod (const vector &v);
};
class matrix{ public:
long m, n;
double *a;
matrix(long nr, long nc);
};
}
Each module "cpp file# contains one unnamed namespace that can be added to by
namespace without identifier i.e. namespace {...}
Eembers of the given namespace can be accessed by the fully qualified name with
scope resolution operator ::, using directive or using declaration.
Example of using namespaces "assuming the previous definition EatHec0alc#'
double MatVecCalc::vector::norm(){ // fully qualified method name
double norm = 0.0;
for (long i=0; i<n; i++)
norm += a[i]*a[i];
return norm;
}
Example of using namspeces 7 continuation'
using namespace MatVecCalc; // using directive
// all declarations from the MatVecCalc can be used unqualified
double vector::dotprod (vector &v){
double ret=0.0;
for (long i=0; i<n; i++)
ret += a[i]*v.a[i];
return ret;
}
or
using MatVecCalc::vector; // using declaration
// declaration of class vector from the MatVecCalc
// can be used unqualified
double vector::dotprod (vector &v){
double ret=0.0;
for (long i=0; i<n; i++)
ret += a[i]*v.a[i];
return ret;
}
f the header file is included %ithout the suffix .h than the the using directive
or fully qualified names have to be used for standard library functions'
#include <cmath> // math.h C standard library
#include <iostream> // iostream.h C++ standard library
=pening of streams can be performed either by the constructor call or by the call of
open() method
!5" E:$e2t*o)0
!8" Tem2late0
!<" #ta)dard Tem2late L*brary
iterators
functors
!?" Creat*)( "e:e %*le0 B l*brar*e0
$epending on the problem solved, the programming task can have two principal
results'
Librar, file . library file contains data and code of functions which are used for
similar purposes "solution of equation systems, export of results to the different file
formats, L #. These files can be provided by the compiler package "&tandard 0%011
library#, third7party libraries "numerical or graphic libraries# or it can be generated
from the user source files due to better management of the source code and%or due to
re7usability of code. There are two basic types of the library files'
1) 6&a&ic librar, 7 "*.lib in /indows or lib*.a in )inux#
These files are linked to the exe7file at compile time.
Pros: simple handling of the application "one exe7file, no additional source
code#, minor compatibility issues due to changes in =& or third7party
libraries
'ons: large%huge executable files slower application startup, higher
memory requirements, all application has to be recompiled due to
change in one library.
1) -,namic'lin7 librar, 7 "*.dll in /indows or *.so in )inux#
$ynamic7link library files are shipped together with the exe7files and they are
"un#linked%"un#loaded at runtime on request.
Pros: compact si6e of exe7file, program update can be done without
recompilation of the executable files, dynamic management of the
memory occupied by the program.
'ons: compatibility issues due to third7party or =& $)) libraries, additional
code is necessary for handling of $)) "loading%unloading%registering#
0ompilation of the source file is decomposed into three steps'
,RE,ROCESSIN- CO$,I.ATION .IN/IN-
8re*rocessing . all symbolic macros are replaced by their values, all header files are
included into the source file.
Preprocessing is performed by the *re*rocessor tool. The resulting file is sent to the
compiler.
Eost reported errors of the preprocessor'
() missing )eader #ile%
*) missing pairs #if&#endif.
The postprocessor does ;=T perform s$nta+ c)ec,ing nor semantic c)ec,ing.
E.g.,the preprocessor does not detect unmatched braces in source files nor in header
files and such errors can be hardly revealed.
2or these purposes, the preprocessor usually enables output of the preprocessing
result to the text file which can be reviewed in a text editor.
!?"! Com2*le B L*)*)( 'ro$e00e0
Lin7ing . resulting target is created by the lin7er, which assembles object files
generated by the compiler and used libraries together. The linker creates either exe7
file or library"ies#.
n the case of exe7file and dynamic7link libraries, the relative addresses in the used
object files are relocated to the final addressing system and the linker generates so
called reloca&ion &able.
n the case of static libraries, the object files are connected into one large file and the
table of the library content is appended. (ddresses still remain relative.
!nknown function or global variable are the most reported errors of the linker.
+# The function is reported as unknown in the cases'
Each application can be composed from several exe7files, static libraries "*.lib,
lib*.a#, dll7libraries "*.dll, lib*.so# and other resources. Nenerally, the
following steps are necessary in the particular $Es for the creation and managing of
the application'
+# 0reate new *ro)ec& "solu&ion . E& H&011%*ro)ec& grou* . 011 5uilder# 7 it
will contain all necessary files for the application build7up.
:# 0reate particular *ro)ec& &arge&s "*ro)ec& . E& H&011%*ro)ec& . 011 5uilder# .
each target represents one binary result such as exe7file, static library "*.lib,
lib*.a#, dll7library "*.dll, lib*.so# or other resource files.
*# &etup of &arge& o*&ions . the following items have to be specified especially'
compiler options "path of include files, path of static libraries, debug info
options, optimi6ing switches, type of processor, L#
Log messages, log files . errors are written to the output device "stdio%stderr%log file#
3rror handlers . special functions for error handling called after an error occurs.
Error context is indicated by the return value "error code# or%and error flag variable
"global variable#. This system is used in 0 library . errno, perror and
strerror.
Pros' fast execution, smaller generated code
'ons' large amount of source lines for the error handling "testing of return values#,
hard maintenance of the source code.
Condi&ional com*ila&ion < source code used for the debugging purposes should be
made optional by the directive #ifdef __DEBUG__ #endif.
Commen&ing ou& . parts of source code can be commented out in order to identify the
source of error in the large code.
&oftware debugging tools'
$ebuggers use special informations connected with the generated machine code. The
generation of these debug informa&ions5s,mbols can be turn on%off within the
compiler. These informations are stored either directly in the exe7file or in the
separate file. The list of the most used debuggers follows'
+# /;$5N , E& Hisual &tudio . E& /indows, enables Edit70ontinue debugging
:# 011 5uilder debugger . E& /indows, enables Edit70ontinue debugging
*# /(T0=E debugger . E& /indows
,# N$5 . )inux
-# H()N>;$ . )inux memory debugger
9# T=T()HE/ . )inux, !nix, Eac =&< "even for debugging of parallel codes#
2ormats of debug symbols and corresponding file suffix in the case that they are
generated separately'
+# 0odeHiew . old E& format O.$5NP . E& Hisual &tudio -.4, /atcom 011,
:# Program $atabase . new E& format O.P$5P . E& Hisual &tudio 9.4 and later
*# T$& . 5orland Turbo $ebugger &ymbol O.T$&P . 011 5uilder, 5orland 011
,# $/(>2 . &tandardi6ed debugging format O.&QEP . /atcom, N$5, TotalHiew
The following terminology is used in most debuggers'
=rea7*oin& . &etting breakpoint on the given source line makes the program
stop at this line each time.
Call56&ac7 &race5&ree . shows the actual call tree starting from the actual
function and finishing the main() function. The call tree represents the path
which was passed by the the program from the main() function to the current
source line.
The following terminology and commands are used in most debuggers'
>un%?o . runs the program until the next breakpoint or end of program
6&e*%;race over . actual source line is performed without stepping into function
call
6&e*%;race in&o . actual source line is performed and in the case of function call
the program stops at the first line of function called
>un un&il re&urn . the program runs until the return from the actual function
:ssembl, . shows the assembler instructions "machine code# of the given source
file%line.
9emor, . shows the window with the memory content starting from the given
address. $ifferent view to the memory content are supported usually 7 0har "8bit#,
/ord"+9bit#, $/ord "*:bit#, float, double, pointer, etc.