LECTURE 11 and 12
Introduction to programming in C++ language
See examples
ex_??.cpp
taken from book
Jerzy Grębosz „Symfonia C++”
Tomasz Zieliński
WHAT IS NEW IN C++?
(1)
C++
=
C
plus
classes (object-oriented operations and functions)
VISUAL C++
=
C++
plus
classes of graphical objects / functions
C#
=
C++
plus
classes of network objects / functions
MATLAB
=
C++
plus
classes of mathematical objects (matrices)
♦ class
= data structures + functions acting on them
♦ inheritance
= one class can be a part of other “bigger” classes
B
A
B
A
C
B
single
inheritance
multiple
inheritance
♦ encapsulation
private
- variables available only for
inner
functions of the class
protected
- variables available also for
derivative
classes
public
- variables available for all classes
WHAT IS NEW IN C++?
(2)
♦ polymorphism
(object-orientation, multi-sense/meaning, virtuality)
• virtual functions
– their behavior depends on which types of objects
they are executed (e.g. function „play_a_sound” in ex_24.cpp)
• „overloading” function names
– a few different functions, having the
same name, are recognized (differentiated) by different order of
types (char, int, long, …) of arguments that are sent to them
• „ overloading” arithmetic operators
(+,
−, *, /)
each operator, e.g. „+”, can have a lot of meanings that depend
on its arguments (what is on the left and on the right of it)
e.g. mathematical operations on complex numbers
mathematical operations on vectors and matrices
♦ templates
= mechanism for defining new functions and classes; only
different types of arguments are used or new components are
added
♦ exceptions
(try, catch)
= mechansm for reaction on critical situation
(risky and dangerous for program execution)
WHAT IS NEW IN C++?
(3)
Less important changes:
1) New functions for input (
cin >>
) and output (
cout <<
) in
<iostream.h>
.
2) Possibility of variables declaration at any place, not only in the program
beginning (
on-line
declaration).
3) New variables types (used also in C version
ISO/ANSI C99 (1999)
):
const
after initialization changing variable value is impossible
register
storing a variable in processor’s registers is suggested
volatile
read from memory during any usage
4)
Inline
functions: short functions which code is repeated (embedded)
many times in a program. Thanks to this the program is executed faster.
5) Passing (sending) values of variables to the functions by reference (
&ref
).
6) Dynamic memory allocation using functions
new
and
delete
.
NOTIONS (CONCEPTIONS) ASSOCIATED WITH
CLASSES
♦ constructor
function having the same name as the class. It is used for
initialization of class objects (variables) and return nothing
- openly (publicly) called
- automatic & copying
♦ destructor
function which name is negated name of the class that is
used for removing (“killing”) class objects (variables)
♦ friend
GLOBAL function being a friend of a few classes
and having access to all their objects (variables)
EXAMPLES (1)
1)
cin >>, cout <<
int
i;
float
f;
cout <<
”Give integer number: ”;
cout <<
”Give floating-point: ”;
cin >>
i;
cin >>
f;
2) declaration of
on-line
variable
int i, j;
i=5; j=i+10;
float f;
f=1.2345;
for(
int
k=0; k<10; k++) {...}
3) declaration of variables:
const, register, volatile
const
int
max =10;
register
int i,
j;
valatile
int
AC;
EXAMPLES (2)
4)
inline
function
float gain = 10; offset = 5;
inline
float scale( float x)
{ return( gain *(x-offset) ); }
5) value of function argument sent by reference (
&ref
)
int myfunction( int val, int
&ref
)
{ val = 0; ref = 0; }
main()
{
int a=1,
b=2
, c;
c = myfunction( a,
b
);
cout << a << ”\n” << b;
// ”\n” = endl = new line
}
EXAMPLES (3)
6) dynamic memory allocation:
new
,
delete
float *pa, *ptab;
pa =
new
float;
ptab =
new
float[100];
*pa = 1.2; *ptab = 3.4; ptab[ 99 ] = 5.6;
delete
pa;
delete
[] ptab;
7) overloading function names
void
display
( int i);
void
display
( float f);
void
display
( int i, float f);
void
display
( float f, int i);
// EXAMPLE 7 –
example of class & its objects definition
// Jerzy Grębosz „Symfonia C++”, pp. 271
#include <iostream.h>
#include <string.h>
//====== definition of the
class
having name
person
==========//
class person
{
char surname[ 80 ] ;
int age ;
public :
void store(char *text, int years) ;
// <-- function NOT inline
//---------------------------------------------------
// only declaration
void display()
// <-- function inline
{
// at once definition
cout << "\t" << surname << ", age: " << age << endl ;
}
} ;
//==== definition of the function store() for the class person ====//
void
person::store
(char *text, int years)
// definition of the class
{
// function; NOT inline
strcpy(surname, text) ;
// classname::functionname
age = years ;
}
// ================================================== //
void main()
{
person
student1, student2, professor, pilot ;
// declaration of objects
//
of
the
class
person
cout << "Object of the class person has size: " << sizeof(person) <<
endl;
professor.store( "Albert Einstein", 55 );
student1.store( "John Smith", 21 );
student2.store( "Ann Walker", 23 );
pilot.store( "Neil Armstrong", 37 );
cout << "\nChecking after objects initialization: \n";
cout << "Data from object professor\n";
professor.display();
cout << "Data from object student1\n";
student1.display();
cout << "Data from object student2\n";
student2.display();
cout << "Data from object pilot\n";
pilot.display();
cout << "Hey, you will be a pilot !\n" ;
//
cout << "What is your name? " ;
// Give your family name:
char buffer[80] ;
// declaration on-line
cin >> buffer ;
// reading
cout << "How old are you? " ;
// Give your age:
int
howmany
;
// declaration on-line
cin >> howmany ;
// reading
pilot.store( buffer , howmany);
// new pilot
cout << "Now professor and pilot are : \n ";
professor.display();
pilot.display();
}
// EXAMPLE 8a –
class constructor
// function that initializes values of variables of class objects
// it has the same name as the class and return nothing
// Jerzy Grębosz „Symfonia C++”, pp. 282
#include <string.h>
// since we are using strcpy()
#include <iostream.h>
// as usual: cin >>, cout <<
// ================= class definition =================== //
class number
{
int value ;
char description[40] ;
public:
// auxiliary functions ------------------------
// constructor – only declaration
# function initializing
// has the same name as the class,
# values of variables
// returns nothing
# of the class
number
( int howmany, char *text ) ;
// additional component functions ------
void store(int howmany)
{ value = howmany ; report() ; }
// -------------------------------------------------
int givevalue()
{ return value ; }
// -------------------------------------------------
void report()
{ cout << description << value << endl ; }
} ;
// ============= constructor definition =================== //
number::number
(int howmany, char *text)
// classname::classname
{
//
value = howmany;
// put sent values into class
strcpy( description, text );
// variables: value, description
}
void main()
{
// initialization:
number
airplane=
number
( 1200, "Actual altitude");
// full verion
number
atmosphere=
number
( 920, "Atmospheric Pressure");
// full v.
number
course( 63, "Flight direction");
// short version
// initial report
airplane.report() ;
// execute function report() on
course.report();
// consecutive objects of the class
atmosphere.report();
// number
cout << "\n Flight correction !!!\n\n" ;
airplane.store( 1201 );
// function store() performed on
// the airplane
// change course by 3 degrees
// functions „givevalue”
course.store( course.givevalue() + 3) ;
// and ”store” performed
// on course
// pressure is falling down
atmosphere.store( 919 ) ;
// function store() on atmosphere
}
// EXAMPLE 13 –
GLOBAL function being a friend of a few classes
// has access to all components of these classes (even private)
// Jerzy Grębosz „Symfonia C++”, pp. 306
#include <iostream.h>
#include <string.h>
class square ;
// declaration announcing the second class
// ==================== first class ======================//
class point
{
int x, y ;
char name[30] ;
public :
point
( int a, int b, char *text ) ;
void kick( int n, int m ) { x += n ; y += m ; }
// function
friend int referee
( point &p, square &s ) ;
// <-- being a friend of
} ;
// class point
// ================= second class =====================//
class square
{
int x, y, size;
char name[30] ;
public :
square
( int a, int b, int dd, char *text ) ;
// function
friend int referee
( point &p, square &s ) ;
// <-- being a friend of
} ;
// class square
// ============= constructor of the class point =============//
point::point
( int a, int b, char *text)
{ x = a ; y = b ;
strcpy(name, text) ;
}
// ============ constructor of the class square ============//
square::square
( int a, int b, int dd, char *text)
{ x = a ; y = b ; size = dd ;
strcpy(name, text) ;
}
// this is a friend function of both classes: point and square ==//
int
referee
(point &pt, square &sq)
{
if ( (pt.x >= sq.x) && (pt.x <= (sq.x + sq.size) )
&&
(pt.y >= sq.y) && (pt.y <= (sq.y + sq.size) ) )
{
cout << pt.name << " is on the " << sq.name << endl ;
return 1 ;
}
else
{
cout << "OUT!" << pt.name << " is out of " << sq.name << endl;
return 0 ;
}
}
//====================================================//
void main()
{
square ffield( 10, 10, 40, "court") ;
// football field of class square
point ball( 20, 20, "ball");
// ball of class point
referee
( ball, ffield );
// where is the ball ?
cout << "\nWe are kicking the ball !\n" ;
while(
referee
( ball, ffield ) ) /
/ is the ball on the football field?
{
ball.kick( 20, 20);
// we are kicking the ball
}
}
// EXAMPLE 18 –
overloading arithmetic operators
//
add and multiply complex number using operators
"+", „*”
// Jerzy Grębosz „Symfonia C++”, pp. 422
#include <iostream.h>
// ================================================ //
class complex
{
public :
float re ;
float im ;
complex
( float r = 0, float i = 0): re(r), im(i)
// initialization list:
{ }
// re = r; im = i;
void display()
{ cout << "Complex number: (" << re << ", " << im << ") \n" ; }
} ;
// overloading operator ”+” =========================== //
complex
operator+
( complex a, complex b )
{
complex sum( 0, 0 ) ;
sum.re = a.re + b.re ;
sum.im = a.im + b.im ;
return sum ;
}
// add complex numbers using old-fashion function ====== //
complex
add
( complex a, complex b )
{
complex sum( 0, 0 ) ;
sum.re = a.re + b.re ;
sum.im = a.im + b.im;
return sum;
}
// overloading operator ”*” ========================= //
complex
operator*(
complex a, complex b )
{
complex mult( 0, 0 ) ;
mult.re = a.re * b.re - a.im * b.im ;
mult.im = a.re * b.im + a.im * b.re ;
return mult ;
}
// ================================================= //
void main()
{
complex z1( 6, -2 ), z2( -1, 3 ), z3 ;
// definition - initialization
cout << "\n Addition of complex numbers (6,-2) + (-1,3) = \n" ;
z3 = z1 + z2;
// add – overloaded operator +
z3.display();
// show result
z3 = add( z1, z2 );
// add using function
z3.display();
// show result
cout << "\n Multiplication of complex numbers (6,-2) + (-1,3) = \n" ;
z3 = z1 * z2;
// multiply - overloaded operator *
z3.display();
// show result
}
// EXAMPLE 19 -
overloading arithmetic operators
//
multiply a vector by a number using "*"
// Jerzy Grębosz „Symfonia C++”, pp. 438
//===================================================//
class vector
{
public :
float x, y, z ;
// constructor --- initialization list: x=xp, y=yp, z=zp
vector( float xp = 0, float yp = 0, float zp = 0 ): x(xp), y(yp), z(zp)
{ /* empty body */ } ;
} ;
//===================================================//
vector
operator*
( vector vin, float number )
{
vector vout ;
vout.x = vin.x * number ;
vout.y = vin.y * number ;
vout.z = vin.z * number ;
return vout ;
}
//=================================================//
void display( vector vin )
// definition of auxiliary function
{ cout << " " << vin.x
<< " " << vin.y
<< " " << vin.z << endl << endl ;
}
//=================================================//
void main()
{
vector a( 1, 2, 3 ), b( -1.1, -2.2, 3.3 ), c ;
cout << " [ 1, 2, 3 ] * 3.5 =" ;
c = a * 3.5 ;
// multiply vector a by number 3.5
display(c) ;
cout << " [ -1.1, -2.2, 3.3 ] * -2.0 =" ;
c = b * -2.0 ;
// multiply vector b by number –2.0
display(c) ;
}
// EXAMPLE 23 –
multiple inheritance
//
one class is derived (deduced) from a few classes
//
and inherits their data structures and functions
// Jerzy Grębosz „Symfonia C++”, pp. 525
//////////////////////////////////////////////////////////////////////////////////////////// first class
class car
{
protected :
int a ;
public:
car(int
arg)
:
a(arg)
// a = arg
{ cout << "Car constructor \n" ; } ;
} ;
////////////////////////////////////////////////////////////////////////////////////////// second class
class boat
{
protected :
int b ;
public:
boat(int x) : b(x)
// b=x
{ cout << "Boat constructor \n" ; }
} ;
///////////////////////////////////// derived class that inherits from two classes
class amphibiancar : public car, public boat
{
public :
amphibiancar() : car(1991) , boat(4)
// initialization list
{ cout << "Amphibiancar constructor \n" ; }
void display_components()
{ cout << "Inherited components \n a = " << a
<< ", b = " << b << endl ; }
} ;
/////////////////////////////////////////////////////////////////////////////////////// main program
void main()
{
amphibiancar xxx ;
xxx.display_components();
}
// EXAMPLE 24 –
virtual functions
// Derived classes have functions with the same names as the “mother”
// (basal) class.
// If we call such functions with an address of derived object,
// then appropriate function of the derived class will be chosen.
// Jerzy Grębosz „Symfonia C++”, pp. 553
/* ----------------- file : e_24.h ---------------- */
#include <iostream.h>
//-------------------------------------------------------
class
instrument
{
// basic class
int price ;
public:
void virtual
play_sound
()
// <-- virtual function
{ cout << " Undetermind bang ! \n" ;
}
} ;
//-------------------------------------------------------
class
trumpet
: public
instrument
{
// derived class no 1
public:
void
play_sound
()
// <-- the same function
{ cout << " Tra-ta-ta ! \n" ; }
//
name
} ;
//-------------------------------------------------------
class
piano
: public
instrument
{
// derived class no 2
public:
void
play_sound
()
// <-- the same function
{ cout << " Pilm-plim-plim ! \n" ; }
//
name
} ;
//-------------------------------------------------------
class
drum
: public
instrument
{
// derived class no 3
public:
void
play_sound
()
// <-- the same function
{ cout << " Bum-bum-bum ! \n" ; }
//
name
} ;
//-------------------------------------------------------
#include
"e_24.h"
// our file
void musician(
instrument
&given_instrument) ;
// function declaration
//--------------------------------------------------------------------------------------------
void main()
{
instrument
any_instrument
;
// object of the basic class
trumpet
golden_trumpet
;
// object of the derived class 1
piano
steinway_giseli
;
// object of the derived class 2
drum
my_drum
;
// object of the derived class 3
cout << "Ordinary call of component functions for different objects \n"
"- till now nothing special \n" ;
any_instrument.
play_sound
() ;
golden_trumpet.
play_sound
() ;
steinway_giseli.
play_sound
() ;
my_drum.
play_sound
() ;
cout << "And know we executed the function on object \n"
"depicted by pointer to an instrument \n" ;
instrument
*ptrinstr ;
// pointer declaration
ptrinstr = &
any_instrument
;
// pointer initialization (setting)
ptrinstr ->
play_sound
() ;
// play a sound
cout << "Revelation is observed when we depict with \n”
„the instrument pointer to objects derived from \n"
"the class instrument \n";
ptrinstr = &
golden_trumpet
;
ptrinstr ->
play_sound
() ;
ptrinstr = &
steinway_giseli
;
ptrinstr ->
play_sound
() ;
ptrinstr = &my_drum ;
ptrinstr->
play_sound
() ;
cout << "The similar behavior is observed also for references \n" ;
musician(
any_instrument
);
musician(
golden_trumpet
);
musician(
steinway_giseli
) ;
musician(
my_drum
) ;
}
//--------------------------------------------------------------------------------------------
void musician(
instrument
&given_instrument )
{
given_instrument.
give_sound
();
}