Object Oriented Programming Object Orien
Object Oriented Programming Object Orien
Binnur Kurt
[email protected]
2
Welcome
Welcome to
to the
the Course
Course
Important Course Information
¾ Course Hours
• 10:00-13:00 Thursday
¾ Course Web Page
• http://www.cs.itu.edu.tr/~kurt/courses/blg252e
¾ Join to the group
• http://groups.yahoo.com/group/blg252e
• [email protected]
¾ E-mail
3
Grading
Grading Scheme
Scheme
¾ 3 Homeworks (5% each)
¾ 2 Midterm Exams (20%,25%)
¾ A final exam (40%)
¾ You must follow the official Homework Guidelines
(http://www.ce.itu.edu.tr/lisans/kilavuz.html).
¾ Academic dishonesty including but not limited to cheating,
plagiarism, collaboration is unacceptable and subject to disciplinary
actions. Any student found guilty will have grade F. Assignments
are due in class on the due date. Late assignments will generally not
be accepted. Any exception must be approved. Approved late
assignments are subject to a grade penalty.
4
References
References
5
Tell me and I forget.
Show me and I remember.
Let me do and I understand.
—Chinese Proverb
Reference
Exercise
11
Content
Content
►Introduction to Software Engineering
►Object-Oriented Programming Paradigm
Introduction 1
Software Crisis
– Low quality
– Not met deadlines and cost limits
Maintainability Portability
Flexibility
Introduction 1
Reusability
Testability Interoperability
P R O D U C T R E V IS I O N PRODUCT TRANSITION
PRODUCT OPERATION
Correctness Usability Efficiency
Reliability Integrity
►Design Phase
►Implementation Phase
►Integration Phase
►Maintenance Phase
►Retirement Phase
– Due dates
– Costs
– Reliability
– Size
►Types
– Functional
– Non-Functional
Object Oriented Programming 25
Specification
Specification Phase
Phase
►Documentation of requirements
– Inputs & Outputs
Introduction 1
– Formal
– Understandable for user & developer
– Usually functional requirements. (what to do)
– Base for testing & maintenance
►The contract between customer & developer ?
– Architectural design
– Detailed design
– ...
►Important
– To backtrack the aims of decisions
– To easily maintain
– For verification
– For validation
►Quality tests
– Perfective
– Adaptive
►Usually maintainers are not the same people with
developers.
►The only input is (in general) the source code of the
software?!?
redesigned.
– So many changes may have been made.
– The update frequency of docs is not enough.
– The hardware (or OS) will be changed.
class {
Introduction 1
Abstraction/
Object
Modeling Implementation
Object Object
COMPUTER
REAL WORLD PROGRAMMER
► If successful, this medium of expression (the object-oriented way)
will be significantly easier, more flexible, and efficient than the
alternatives as problems grow larger and more complex.
Object Oriented Programming 35
Learning
Learning C++
C++
► Like human languages, programming languages also have many syntax
and grammar rules.
► Knowledge about grammar rules of a programming language is not
Introduction 1
Analysis/Planning
OO
Design/Modeling
Documentation
Implementation
C++
Test Product
► Risk-driven
something.
► In a procedural language, the emphasis is on doing things
(functions).
►A program is divided into functions and—ideally, at least—
each function has a clearly defined purpose and a clearly
defined interface to the other functions in the program.
Global Data
display the data or functions that checks for correct input; they are
student, teacher data.
► Procedural programs (functions and data structures) don’t model the
real world very well. The real world does not consist of functions.
► Global data can be corrupted by functions that have no business
changing it.
► To add new data items, all the functions that access the data must be
modified so that they can also access these new items.
► Creating new data types is difficult.
worker, manager
– Graphics program: Point, line, square, circle, ...
– Mathematics: Complex numbers, matrix
– Computer user environment: Windows, menus, buttons
– Data-storage constructs: Customized arrays, stacks,
linked lists
real world.
To create software models of real world objects both data and the
functions that operate on that data are combined into a single
program entity. Data represent the properties (state), and functions
represent the behavior of an object. Data and its functions are said
to be encapsulated into a single entity.
the problem.
– Understandability
– Low probability of errors
– Maintenance
– Reusability
– Teamwork
59
C++
C++ As
As aa Better
Better C
C
► C++ was developed from the C programming
language, by adding some features to it. These
features can be collected in three groups:
2
Minor exceptions:
C code that is not C++
Object Oriented Programming 60
C++'s
C++'s Enhancements
Enhancements to
to CC (Non
(Non Object-Oriented)
Object-Oriented)
float re,im;
};
C++ As a Better C
a++;
C++ As a Better C
void f(){
C++ As a Better C
1
int x=2; // Local x
::x++; // Global x is 2
}
int n=i ;
int i = 3 ;
C++ As a Better C
function.
► Remember the difference between normal functions and
macros:
► A normal function is placed in a separate section of code and a
call to the function generates a jump to this section of code.
► Before the jump the return address and arguments are saved in
memory (usually in stack).
Object Oriented Programming 69
inline
inline functions
functions Con’t
► When the function has finished executing, return address and return
value are taken from memory and control jumps back from the end
of the function to the statement following the function call.
2
► The advantage of this approach is that the same code can be called
C++ As a Better C
► Advantages
► Debugging
2
► Type checking
C++ As a Better C
► Readable
►n(3,4) Æ n(3,4,3)
C++ As a Better C
►n(5,6,7) Æn(5,6,7)
n
C++ As a Better C
int n ;
int& nn = n ;
double a[10] ;
double& last = a[9] ;
const char& new_line = '\n' ;
j 5
*a = *b ;
…
C++ As a Better C
*b = temp ; } a adr_i
b adr_j
int main(){
int i=3,j=5 ; stack
swap(&i,&j) ; GDA
adr_j
cout << i << " " << j << endl ;
adr_i
} 53
Object Oriented Programming 80
void swap(int& a,int& b){
int temp = a ;
a=b;
2
b = temp ; }
C++ As a Better C
int main(){
int i=3,j=5 ;
swap(i,j) ;
cout << i << " " << j << endl ;
} 53
Object Oriented Programming 81
void shift(int& a1,int& a2,int& a3,int& a4){
int tmp = a1 ;
a1 = a2 ;
2
a2 = a3 ; int main(){
C++ As a Better C
a3 = a4 ; int x=1,y=2,z=3,w=4;
} shift(x,y,z,w) ;
cout << x << y << z << w << endl;
return 0 ;
}
int main(){
2
squareByPointer(&x) ; }
cout << x << endl ;
squareByReference(y) ;
cout << y << endl ;
4
z = squareByValue(z) ;
9
cout << z << endl ;
16
}
Object Oriented Programming 83
const
const Reference
Reference
►To prevent the function from changing the parameter
accidentally, we pass the argument as constant reference to
the function.
2
►One result of using “return by reference” is that the function which returns a
parameter by reference can be used on the left side of an assignment
statement.
int& max( const int a[ ] , int length) { / / Returns an integer reference
int i= 0; / / indices of the largest element
for (int j= 0 ; j< length ; j+ + )
if (a[ j] > a[ i] ) i = j;
return a[ i] ; / / returns reference to a[ i]
}
int main() {
int array[ ] = { 12, -54 , 0 , 123, 63} ; / / An array with 5 elements
max( array,5) = 0 ; / / write 0 over the largest element
:
{ / / assignment statement
int i= 0; / / indices of the largest element
C++ As a Better C
for(int i=0;i<row;i++)
C++ As a Better C
. .
2
. .
. .
q[i][j]
C++ As a Better C
. .
q[i]
for(int i=1;i<row;i++)
q[i] = q[i-1] + column ;
…..
delete []q[0] ;
delete []q ;
ith row jth column: q[i][j]
q[i]
C++ As a Better C
.
. for (int i=1;i<row;i++)
. q[i] = q[i-1] + column ;
.
q[row-1]
for(int i=0;i<row;i++)
q[i] = q[i-1] + memoryWidth ;
…..
delete []q[0] ;
delete []q ;
double average(const
average int a[],int size) ;
C++ As a Better C
double average(const
average int a[], const double b[],int size) ;
return (sum/size) ;
C++ As a Better C
}
p double average(const int a[],const double b[],int size) {
double sum = 0.0 ;
for(int i=0;i<size;i++) sum += a[i] + b[i] ;
return (sum/size) ;
}
double x[5]={1.1,2.2,3.3,4.4,5.5} ;
double b[5]={1.1,2.2,3.3,4.4,5.5} ;
C++ As a Better C
o printArray(b,5) ;
p printArray(c,7) ;
return 0 ;
}
}
void printArray(char *array,cont int size){
for(int i=0;i < size;i++)
cout << array[i] ;
cout << endl ;
}
struct SComplex{
float real,img;
};
SComplex operator+(SComplex v1, SComplex v2){
SComplex result; int main(){
result.real=v1.real+v2.real; SComplex c1={1,2},c2 ={5,1};
result.img=v1.img+v2.img; SComplex c3;
return result; c3=c1+c2; // c1+(c2)
} }
Object Oriented Programming 102
namespace
namespace
►When a program reaches a certain size it’s typically broken up into pieces,
each of which is built and maintained by a different person or group.
2
►Since C effectively has a single arena where all the identifier and function
names live, this means that all the developers must be careful not to
C++ As a Better C
accidentally use the same names in situations where they can conflict.
►The same problem come out if a programmer try to use the same names as
the names of library functions.
: // other variables
C++ As a Better C
} // end of namespace
namespace G { return 0;
using namespace F; }
float y = 2.0;
namespace INNER_G {
long x = 5L;
float z = 10.01;
}
}
Object Oriented Programming 108
namespace
namespace
#include <iostream> int main() {
namespace F { using namespace G;
float x = 9;
2
namespace G { return 0;
float y = 2.0; }
namespace INNER_G {
long x = 5L;
float z = 10.01;
}
}
namespace G { return 0;
float y = 2.0; }
namespace INNER_G {
long x = 5L;
float z = 10.01;
}
}
►As C++ evolved, different compiler vendors chose different extensions for
file names (.hpp, .H , etc.). In addition, various operating systems have
C++ As a Better C
►To solve these problems, the standard uses a format that allows file names
longer than eight characters and eliminates the extension.
►For example, instead of the old style of including iostream.h, which looks
like this: #include <iostream.h>, you can now write: #include
<iostream>
►In standard C++ headers all declarations and definitions take place in a
namespace : std
►Today most of C++ compilers support old libraries and header files
too. So you can also use the old header files with the extension '.h'. For a
high-quality program prefer always the new libraries.
int main() {
int i=5; // integer i is defined, initial value is 5
float f=4.6; // floating point number f is defined, 4.6
std::cout << "Integer Number = " << i << " Real Number= " << f;
return 0;
}
stream uses the >> operator, usually called the "get from"
operator.
C++ As a Better C
#include<iostream>
using namespace std; // we don't need std:: anymore
int main() {
int i,j; // Two integers are defined
cout << "Give two numbers \n"; // cursor to the new line
cin >> i >> j; // Read i and j from the keyboard
cout << "Sum= " << i + j << "\n";
return 0;
}
Object Oriented Programming 115
std namespace
std namespace
#include <string>
#include <iostream>
2
int main() {
string test;
while(test.empty() || test.size() <= 5)
{
cout << "Type a string longer string. " << endl;
cin >> test;
}
printf(“%s”,test.c_str())
Object Oriented Programming 116
bool Type
bool Type
The type bool represents boolean (logical) values: true and false
Before bool became part of Standard C++, everyone tended to use different
techniques in order to produce Boolean-like behavior.
2
Because there’s a lot of existing code that uses an int to represent a flag, the
compiler will implicitly convert from an int to a bool (nonzero values will
produce true while zero values produce false).
Do not prefer to use integers to produce logical values.
bool is_greater; // Boolean variable: is_greater
is_greater = false; // Assigning a logical value
int a,b;
………………
is_greater = a > b; // Logical operation
if (is_greater) …… // Conditional operation
Object Oriented Programming 117
constant
constant
►In standard C, preprocessor directive #define is used to create
constants: #define PI 3.14
►C++ introduces the concept of a named constant that is just like a
2
constant:
const int MAX = 100;
…
MAX = 5; // Compiler Error!
►const can take place before (left) and after (right) the type. They are
always (both) allowed and equivalent.
int const MAX = 100; // The same as const int MAX = 100;
►Decreases error possibilities.
►To make your programs more readable, use uppercase font for
constant identifiers.
Object Oriented Programming 118
Use
Use of
of constant–1
constant–1
Another usage of the keyword const is seen in the declaration of pointers.
There are three different cases:
a) The data pointed by the pointer is constant, but the pointer itself
2
Example: f = (float)i / 2;
Following that, C++ initially also supported the function call style cast
C++ As a Better C
notation:
typename(expression)
Example: Converting an integer value to a floating point value
int i=5;
float f;
f = float(i)/2;
►But, these casts are now called old-style casts, and they are
deprecated. Instead, four new-style casts were introduced.
Object Oriented Programming 122
Casts:
Casts: static_cast
static_cast
►The static_cast<type>(expression) operator is used to convert one
type to an acceptable other type.
2
int i=5;
float f;
C++ As a Better C
f = static_cast<float>(i)/2;
struct S{ // A structure
int i1,i2; // made of two integers
C++ As a Better C
};
int main(){
S x; // x is of type S
x.i1=1; // fields of x are filled
x.i2=2;
unsigned char *xp; // A pointer to unsigned chars
xp = reinterpret_cast<unsigned char *> (&x);
for (int j=0; j<8; j++) // bytes of x on the screen
std::cout << static_cast<int>(*xp++);
return 0;
}
The structure S is made of two integers (2x4=8 bytes). x is a variable of type S.
Each byte of x can be reached by using the pointer xp.
Object Oriented Programming 125
Casts:
Casts: dynamic_cast
dynamic_cast
The dynamic_cast<>() operator is used in the context of inheritance
and polymorphism. We will see these concepts later. The discussion of
this cast is postponed until the section about polymorphism.
2
127
Content
Content
►OOP Concepts
– Class
OO Programming Concepts 3
• Encapsulation
• Information Hiding
– Inheritance
– Polymorphism
Hour
int minute; Minute
Second
int second ;
OO Programming Concepts 3
public: SetTime()
GetHour()
// Get Functions GetMinute()
int GetHour(){return hour;} ; GetSecond()
SetHour()
int GetMinute(){return minute;} ; SetMinute()
int GetSecond (){return second;} ; SetSecond()
PrintTim e()
// Set Functions
void SetTime(int h,int m,int s){hour=h;minute=m;second=s;};
void SetHour(int h){hour= (h>=0 && h<24) ? h : 0;} ;
void SetMinute(int m){minute= (m>=0 && m<60) ? m : 0;} ;
void SetSecond(int s){second= (s>=0 && s<60) ? s : 0;} ;
void PrintTime();
};
Object Oriented Programming 136
C++
C++ Terminology
Terminology
► A class is a grouping of data and functions. A class is very much
like a structure type as used in ANSI-C, it is only a pattern to be
OO Programming Concepts 3
int main()
{
Point array[ 10] ; / / defining an array with ten objects
array[ 0] .move(15, 40); / / 'move' message to the first element (indices 0)
array[ 1] .move(75, 35); / / 'move' message to the second element (indices 1)
: / / message to other elements
for (int i = 0; i < 10; i+ + ) / / 'print' message to all objects in the array
array[ i] .print();
return 0;
}
the client programmer can’t use it, which means that the
class creator can change the hidden portion at will without
worrying about the impact to anyone else.
►This protection also prevents accidentally changes of
states of objects.
and functions.
►Private class members can be accessed only by members
of that class.
►Public members may be accessed by any function in the
program.
►The default access mode for classes is private: After each
label, the mode that was invoked by that label applies until
the next label or until the end of class declaration.
point1.move(100,45) point1.print()
void
move(int,int) void
x print()
private
y members
Interface
public members bool is_zero() if( point1.is_zero() )
int main() {
Point p1; // p1 object is defined
int x,y; // Two variables to read some values from the keyboard
cout << " Give x and y coordinates “;
cin >> x >> y; // Read two values from the keyboard
if( p1.move(x,y) ) // send move message and check the result
p1.print(); // If result is OK print coordinates on the screen
else cout << "\nInput values are not accepted";
}
It is not possible to assign a value to x or y directly outside
the class.
p1.x = -10; //ERROR! x is private
Object Oriented Programming 147
struct Keyword
struct Keyword in
in C++
C++
►class and struct keywords have very similar meaning in
OO Programming Concepts 3
the C++.
►They both are used to build object models.
►The only difference is their default access mode.
►The default access mode for class is private
►The default access mode for struct is public
move
When an object is defined, y=50
memory is allocated only for its point1
data members. print
►The code of member functions are
x=200
created only once. Each object of is_zero
y=300
the same class uses the same
function code. point2
Process Model
OO Programming Concepts 3
Point o;
heap
S
stack o
text main()
o.move(1,1);
data
Process Model
Point *p;
heap
S
stack p ?
text main()
data
OO Programming Concepts 3
Object Oriented Programming 155
Summary
Summary
stack p
text main()
p->move(1,1);
data
(*p).move(1,1);
S
p p[1].move(1,1);
move(1,1)
p p= new Point[10];
H
p[1].move(1,1);
move(1,1)
(*(p+1)).move(1,1);
(p+1)->move(1,1);
159
Content
Content
►Constructors
Initializing and Finalizing Objects 4
– Default Constructor
– Copy Constructor
►Destructor
arguments.
class Point{ / / Declaration Point Class
int x,y; / / Properties: x and y coordinates
public:
Point( ) ; / / Declaration of the default constructor
bool move(int, int); / / A function to move points
void print(); / / to print coordinates on the screen
};
Point::Point( ) { / / Default Constructor
cout < < "Constructor is called..." < < endl;
x = 0; / / Assigns zero to coordinates
y = 0;
}
int main() {
Point p1, p2; / / Default construct is called 2 times
Point * pp = new Point; / / Default construct is called once
Object Oriented Programming 163
Constructors
Constructors with
with Parameters
Parameters
► Like other member functions, constructors may also have
parameters.
Initializing and Finalizing Objects 4
► This declaration shows that the users of the Point class have to give
two integer arguments while defining objects of that class.
class Point{
public:
Point(int x_first = 0 , int y_first = 0 );
:
};
Point::Point(int x_first, int y_first) {
if ( x_first < 0 ) / / I f the given value is negative
x = 0; / / Assigns zero to x
else x = x_first;
if ( y_first < 0 ) / / I f the given value is negative
y = 0; / / Assigns zero to x
else y = y_first;
}
►Now, client of the class can create objects
Point p1(15,75); // x=15, y=75
Point p2(100); // x=100, y=0
►This function can be also used as a default constructor
Point p3; // x=0, y=0
Object Oriented Programming 166
Multiple
Multiple Constructors
Constructors
► The rules of function overloading is also valid for constructors. So, a
Initializing and Finalizing Objects 4
class may have more than one constructor with different type of
input parameters.
Point::Point() { / / Default constructor
............... / / Body is not important
}
const int CI ;
int x;
public:
C() : CI (0) {
x = -2;
}
class C{ };
const int CI ;
int x; All data members of a class
public: can be initialized by using
C( int a ) : CI (0), x (a) constructor initializers.
{ }
};
Object Oriented Programming 172
Destructors
Destructors
►The destructor is very similar to the constructor except
that it is called automatically
Initializing and Finalizing Objects 4
Shallow Copy
size: 8 8 size
► The programmer must write its own copy constructor to perform these
operations.
size: 8 8 size
contents: 0x008d0080 Deep Copy 0x00ef0080
1 1
\0 \0
Object Oriented Programming 178
Example:
Example: The
The copy
copy constructor
constructor of
of the
the String
String class
class
class String {
int size;
Initializing and Finalizing Objects 4
char * contents;
public:
String(const char * ); // Constructor
String( const String &) ; // Copy Constructor
void print(); // Prints the string on the screen
~ String(); // Destructor
};
String::String(const String &object_in) { / / Copy Constructor
cout< < "Copy Constructor has been invoked" < < endl;
size = object_in.size;
contents = new char[ size + 1] ; / / + 1 for null character
strcpy(contents, object_in.contents);
}
int main() {
String my_string("string 1");
my_string.print();
String other = my_string; / / Copy constructor is invoked
String more(my_string); / / Copy constructor is invoked
A a,b,c;
{
std::cout<<"\n Entering 2. BLOCK............";
A d,e;
std::cout<<"\n Exiting 2. BLOCK............";
}
std::cout<<"\n Exiting 1. BLOCK............";
}
Constructor 3
Entering 2. BLOCK............
Constructor 4
Constructor 5
Exiting 2. BLOCK............
Destructor 5
Destructor 4
Exiting 1. BLOCK............
Destructor 3
Destructor 2
Destructor 1
Object Oriented Programming 187
Passing
Passing Objects
Objects to
to Functions
Functions as
as Arguments
Arguments
► Objects should be passed or returned by reference unless there are
compelling reasons to pass or return them by value.
Initializing and Finalizing Objects 4
constructor im numerator
Fraction print()
denominator
constructor ComplexFrac
print()
public:
Fraction(int, int); / / CONSTRUCTOR
void print() const;
};
Fraction::Fraction(int num, int denom) { / / CONSTRUCTOR
numerator = num;
if (denom= = 0) denominator = 1;
else denominator = denom;
cout < < "Constructor of Fraction" < < endl;
}
void Fraction::print() const {
cout < < numerator < < "/ " < < denominator < < endl;
}
Object Oriented Programming 192
Example: A class to define complex numbers. It contains two objects as
members
class ComplexFrac { / / Complex numbers, real and imag. parts are fractions
Fraction re, im ; / / objects as data members of another class
Initializing and Finalizing Objects 4
public:
ComplexFrac(int,int); / / Constructor
void print() const;
};
ComplexFrac::ComplexFrac(int re_in, int im_in) : re( re_in, 1) , im( im_in, 1)
{
:
}
void ComplexFrac::print() const { Data members are initialized
re.print();
im.print();
}
int main() { When an object goes out of scope, the
ComplexFrac cf(2,5); destructors are called in reverse order:
cf.print();
The enclosing object is destroyed first,
return 0;
} then the member (inner) object.
Object Oriented Programming 193
Working
Working with
with Multiple
Multiple Files
Files
(Separate
(Separate Compilation)
Compilation)
Initializing and Finalizing Objects 4
COMPILER
LINKER
executable
197
Operator
Operator Overloading
Overloading
►It is possible to overload the built-in C++ operators such
as +, >=, and ++ so that they invoke different functions,
depending on their operands.
Operator Overloading 5
►a+b will call one function if a and b are integers, but will
call a different function if a and b are objects of a class.
►Operator overloading makes your program easier to write
and to understand.
►Overloading does not actually add any capabilities to C++.
Everything you can do with an overloaded operator you
can also do with a function.
►However, overloaded operators make your programs
easier to write, read, and maintain.
will make the code involving your class easier to write and
especially easier to read.
►Remember that code is read much more than it is written
.
*
->
,
::
?:
sizeof
: // Member functions
TComplex operator+(TComplex&); // header of operator+
function
};
/* The Body of the function for operator + */
TComplex TComplex::operator+(TComplex& z) {
TComplex result;
result.real = real + z.real; int main() {
result.img = img + z.img;
return result; TComplex z1,z2,z3;
} : // Other operations
z3=z1+z2; like z3 = z1.operator+(z2);
}
Object Oriented Programming 202
Overloading
Overloading the
the Assignment
Assignment Operator
Operator (=)
(=)
►Because assigning an object to another object of the same
type is an activity most people expect to be possible, the
compiler will automatically create a type::operator=(const
Operator Overloading 5
re = z.re;
im = z.im;
}
public:
void operator=(const string &); // assignment operator
: // Other methods
};
void string::operator=(const string &s)
{
size = s.size;
delete []contents;
contents = new char[size+1];
strcpy(contents, s.contents);
}
Object Oriented Programming 206
Operator
Operator Provided
Provided by
by the
the Compiler
Compiler
8
0x008d0080 0x008d0080
0x00185d12
contents: contents X
s a
t b
r c
i \0
n
g Data is still wasting
memory space.
1
\0
0x008d0080 0x00185d12
0x00ef0080
contents contents
X
s s a
t t b
r r c
i i \0
n n
g g
1 1
\0 \0
►b=a;
►A c=a;
};
If c is an object of class C, the expression
c(i, j, k) is interpreted as
c.operator( )( i, j, k )
Example: The function call operator is overloaded to print complex
numbers on the screen. In this example the function call operator does
not take any arguments.
/ / The function call operator without any argument, it prints a complex number
void ComplexT:: operator( ) ( ) const {
cout < < re < < " , " < < im < < endl ;
}
Object Oriented Programming 217
Example: The function call operator is overloaded to copy a
part of the contents of a string into a given memory location.
In this example the function call operator takes two arguments:
the address of the destination memory and the numbers of
characters to copy.
Operator Overloading 5
ComplexT temp;
temp = *this; // old value (original objects)
re= re + 0.1; // increment the real part
return temp; // return old value
}
222
Content
Content
►Inheritance
►Reusability in Object-Oriented Programming
6
►Access Control
►Public and Private Inheritance
►Constructor, Destructor and Assignment Operator in
Inheritance
►Multiple Inheritance
►Composition vs Inheritance
situation.
►Once a class has been created and tested, it should
(ideally) represent a useful unit of code.
►This code can be used in different ways again.
little details.
Inheritance
► You can assign to any string object using ‘=’. This replaces the
Inheritance
►The base class does not need any special syntax. The
derived class, on the other hand, must indicate that it’s
Inheritance
public:
void setName (const string & new_name) { name = new_name; }
void print() const;
};
has two member functions with the same name. But this is
not overloading, it is overriding.
Inheritance
};
Inheritance
B b;
int j=b.fa2(1);
b.ia1=4; // B::ia1
b.ia2=3; // A::ia2 if ia2 is public in A
float y=b.fa1(3.14); // B::fa1
b.fa1(); // ERROR fa1 function in B hides the function of A
b.A::fa1(); // OK
b.A::ia1=1; // OK
}
Object Oriented Programming 244
Example
Example
6
A::ia1
3 A::ia2 b.ia1=4;
b.ia2=3;
Inheritance
4 B::ia1
public: };
Inheritance
void fa1();
int fa2(int);
}; float B::fa1(float f){
ia1= 2.22 ;
ia2=static_cast<int>(f*f);
}
};
class Principal : public Teacher { // Derived class
private: // Default
string school_name;
int numOfTeachers;
public:
void setSchool(const string & s_name) { school_name = s_name; }
void print() const;
int getAge() const { return age; } // It works because age is protected
const string & get_name(){ return name;}// ERROR! name is private
};
Object Oriented Programming 248
int main()
{
teacher t1;
6
principal p1;
Inheritance
t1.numberOfStudents=54;
t1.setName(“Sema Catir");
p1.setSchool(“Halide Edip Adivar Lisesi");
}
class. Anyone can derive one class from another and thus gain access
to the base class’s protected data. It’s safer and more reliable if derived
classes can’t access base class data directly.
►But in real-time systems, where speed is important, function calls to
access private members is a time-consuming process. In such systems
data may be defined as protected to make derived classes access data
directly and faster.
251
Public
Public Inheritance
Inheritance
►In inheritance, you usually want to make the access
specifier public.
6
class Base
{ };
Inheritance
private
protected
6
public
Inheritance
protected protected
ObjB ObjC
►If you want any of them to be visible, just say their names
(no arguments or return values) along with the using
keyword in the public section of the derived class:
public:
d.f(); // OK
int i;
Inheritance
return 0;
void f();
};
};
class Derived : private Base{ // All members of Base are private now
int m;
public:
Base::f(); // f() is public again
void fb1();
};
public:
d.f(); // OK
int i;
Inheritance
return 0;
void f(int);
};
bool f(int,float);
};
class Derived : private Base{ // All members of Base are private now
int m;
public:
Base::f(int); // f(int) is public again
void fb1();
};
Object Oriented Programming 257
Special
Special Member
Member Functions
Functions and
and Inheritance
Inheritance
►Some functions will need to do different things in the base class and
the derived class. They are the overloaded = operator, the destructor,
and all constructors.
6
int main() {
Principal p1("Ali Bilir", 20); / / An object of derived class is defined
return 0;
}
►If the base class has a constructor, which must take some arguments, then
the derived class must also have a constructor that calls the constructor of
the base with proper arguments. 260
Destructors
Destructors and
and Inheritance
Inheritance
►Destructors are called automatically.
►When an object of the derived class goes out of scope, the
6
};
class C : public B {
Inheritance
public:
C() { cout << "C constructor" << endl; }
~C() { cout << "C destructor" << endl; }
};
int main(){
std::cout << "Start" << std::endl;
C ch; // create a C object
std::cout << "End" << std::endl;
}
Object Oriented Programming 262
#include <iostream.h>
class A { Example:
Example: Constructor
Constructor Chain
Chain
private:
int x;
float y; class C : public B {
private:
public:
int r;
A(int i, float f) : float s;
x(i), y(f) // initialize A public:
{ cout << "Constructor A" << endl; } C(int i1,float f1, int i2,float f2,int i3,float f3) :
void display() { B(i1, f1, i2, f2), // initialize B
cout << intA << ", " << floA << "; ";} r(i3), s(f3) // initialize C
}; { cout << "Constructor C" << endl; }
class B : public A { void display() {
B::display();
private: cout << r << ", " << s;
int v; }
float w; };
public:
B(int i1, float f1, int i2, float f2) :
A(i1, f1), // initialize A int main() {
v(i2), w(f2) // initialize B C c(1, 1.1, 2, 2.2, 3, 3.3);
{ cout << "Constructor B" << endl; }
void display(){ cout << "\nData in c = ";
A::display(); c.display();
cout << v << ", " << w << "; "; } example19.cpp
}
}; 263
Explanation
Explanation
►A C class is inherited from a B class, which is in turn
inherited from a A class.
►Each class has one int and one float data item.
6
initialize the data for the class and all ancestor classes. This
means two arguments for the A class constructor, four for B
(which must initialize A as well as itself), and six for C
(which must initialize A and B as well as itself).
►Each constructor calls the constructor of its base class.
any arguments.
►The compiler ensures that all destructors are called, and
Inheritance
class String {
Inheritance
protected:
int size;
char * contents;
public:
const String & operator= (const String &); / / assignment operator
: / / Other methods
};
const String & String:: operator = (const String &in_object) {
size = in_object.size;
delete[ ] contents; / / delete old contents
contents = new char[ size+ 1] ;
strcpy(contents, in_object.contents);
return * this;
}
Object Oriented Programming 267
►Example: Class String2 is derived from class String. If an
assignment operator is necessary it must be written
class String2 : public String { / / String2 is derived from String
int size2;
char * contents2;
6
public:
const String2 & operator= (const String2 &);
Inheritance
:
};
/ / * * * * Assignment operator for String2 * * * *
const String2 & String2::operator= (const String2 &in_object) {
size = in_object.size; / / inherited size
delete [ ] contents;
contents= strdup(in_object.contents);
size2 = in_object.size2;
delete[ ] contents2;
contents2 = strdup(in_object.contents2);
return * this;
}
Object Oriented Programming 268
In previous example, data members of String (Base) class must be protected . Otherwise
methods of the String2 (Derived) can not access them.
The better way to write the assignment operator of String2 is to call the assignment
operator of the String (Base) class.
Now, data members of String (Base) class may be private.
/ / * * Assignment operator * *
6
In this method the assignment operator of the String is called with an argument of type
(String2 & ). Actually, the operator of String class expects a parameter of type (String & ).
This does not cause a compiler error, because as we will se in Section 7, a reference to
base class can carry the address of an object of derived class.
one of the data items in this class is the teacher’s name, I can
say that a Teacher object has a name.
Inheritance
a.f( ).
►Notice that the only time you can talk about redefinition
of functions is during inheritance; with a member object you
can only manipulate the public interface of the object, not
redefine it.
►In addition, calling f( ) for an object of class C would not
call a.f( ) if C::f( ) had not been defined, whereas it would
call B::f( ).
Object Oriented Programming 273
Multiple
Multiple Inheritance
Inheritance
class Base1{ // Base 1 int main(){
public: Base1 Base2 Deriv d;
int a;
void fa1(); d.a=4;
6
int i=d.fc();
class Base2{ // Base 2
public:
}
Deriv
int a; example20.cpp
char *fa2(int, char*);
int fc();
char * c=d.fa2(1);
};
is not valid.
class Deriv : public Base1 ,public Base2{ In inheritance functions are not
public: overloaded. They are overridden.
int a; You have to write
float fa1(float); char * c=d.Base1::fa2(1);
int fb1(int); or
};
char * c=d.Base2::fa2(1,"Hello");
Object Oriented Programming 274
Repeated
Repeated Base
Base Classes
Classes Gparent
class Gparent
{ };
class Mother : public Gparent Mother Father
{ };
6
int gdata;
};
Inheritance
{ };
class Mother : virtual public Gparent
Inheritance
{ };
class Father : virtual public Gparent
{ }; example21.cpp
class Child : public Mother, public Father
{ };
►The virtual keyword tells the compiler to inherit only one subobject
from a class into subsequent derived classes. That fixes the ambiguity
problem, but other more complicated problems arise that are too
complex to delve into here.
►In general, you should avoid multiple inheritance, although if you
have considerable experience in C++, you might find reasons to use it in
unusual situations.
Object Oriented Programming 277
class Base
{
public:
int a,b,c; Base
6
};
class Derived : public Base
Inheritance
{ Drived
public:
int b;
};
Derived2
class Derived2 : public Derived
{
public:
int c;
};
class B {
...
Inheritance
}; B
class C { A C
...
};
class D : public A, public B, private C { D
...
};
class A : public L {
L L
Inheritance
...
};
class B : public L {
... A B
};
class C : public A, public B { C
void f() ;
...
};
};
class A : virtual public L { L
Inheritance
...
};
class B : virtual public L { A B
...
}; C
class C : public A, public B {
...
};
... B B
};
Inheritance
... B B
};
Inheritance
class Y : public B { X Y Z
...
};
class Z : public B { AA
...
};
class AA : public X, public Y , public Z {
...
};
... B
};
Inheritance
285
Pointers
Pointers to
to Objects
Objects
►Objects are stored in memory, so pointers can point to
objects just as they can to variables of basic types.
The new Operator:
Object Pointers 7
};
Object Pointers 7
};
Derived d;
Base *bp = &d; // implicit conversion
Derived *dp = bp; // ERROR! Base is not Derived
dp = static_cast<Derived *>(bp); // explicit conversion
297
Content
Content
►Polymorphism
►Virtual Members
►Abstract Class
8
Polymorphism
public:
Polymorphism
else ptr=&C ;
ptr→area();
area // which Area ???
Polymorphism
► ptr = &C;
► Remember that it’s perfectly all right to assign an address of one
type (Derived) to a pointer of another (Base), because pointers to
objects of a derived class are type compatible with pointers to
objects of the base class.
► Now the question is, when you execute the statement
ptr->area();
what function is called? Is it Square::area() or Cube::area()?
Object Oriented Programming 302
Virtual
Virtual Member
Member Functions
Functions Accessed
Accessed with
with Pointers
Pointers
Let’s make a single change in the program: Place the keyword virtual
in front of the declaration of the area() function in the base class.
class Square { // Temel sinif
8
protected:
double edge;
Polymorphism
public:
Square(double e):edge(e){ } // temel sinif kurucusu
virtual double area(){
area return( edge * edge ) ; }
};
class Cube : public Square { // Turetilmis sinif
public:
Cube(double e):Square(e){} // Turetilmis sinif kurucusu
double area(){
area return( 6.0 * edge * edge ) ; }
};
Object Oriented Programming 303
int main(){
Square S(2.0) square.cpp ;
Cube C(8.0) ;
8
Square *ptr ;
char c ;
Polymorphism
string * name;
int numOfStudents;
public:
Teacher(const string &, int); / / Constructor of base
virtual void print() const; / / A virtual (polymorphic) function
};
class Principal : public Teacher{ / / Derived class
string * SchoolName;
public:
Principal(const string &, int , const string &);
void print() const; / / I t is also virtual (polymorphic)
};
Object Oriented Programming 305
Late
Late Binding
Binding
► Now, different functions are executed, depending on the contents of
ptr. Functions are called based on the contents of the pointer ptr, not
on the type of the pointer. This is polymorphism at work. I’ve made
print() polymorphic by designating it virtual.
8
object.
Polymorphism
passes to the function the address of the object that invoked it. This
Polymorphism
There is an entry in each virtual table for every virtual function in the
Polymorphism
};
Polymorphism
50
address of an object.
move.l ptr, this ; this to object vptr
movea.l ptr, a0 ; a0 to object Virtual Table of Principal
movea.l (a0), a1 ; a1< -vptr t2 Teacher 2
jsr 4(a1) ; jsr print 35 &Principal::read
If the print() function would not a &Principal::print
virtual function: vptr
Square S(4);
Polymorphism
Cube C(8);
S.Area();
C.Area();
}
Calling virtual functions is a time-consuming process, because
of indirect call via tables. Don’t declare functions as virtual if
it is not necessary.
Object Oriented Programming 312
Warning
double edge;
public:
Polymorphism
Square(double e):edge(e){ }
virtual double area(){
area return( edge * edge ) ; }
Sqaure *next ;
};
class Cube : public Square {
public:
Cube(double e):Square(e){}
double area(){
area return( 6.0 * edge * edge ) ; }
};
Object Oriented Programming 314
int main(){
Circle c1(50);
Square s1(40);
Circle c2(23);
Square s2(78);
Square *listPtr; // Pointer of the linked list
8
listPtr=&c1;
c1.next=&s1;
s1.next=&c2;
c2.next=&s2;
s2.next=0L;
while (listPtr){ // Printing all elements of the list
cout << listPtr->Area() << endl ;
listPtr=listPtr->next;
}
}
Object Oriented Programming example27.cpp 315
Abstract
Abstract Classes
Classes
► To write polymorphic functions wee need to have derived classes.
But sometimes we don’t need to create any base class objects, but
only derived class objects. The base class exists only as a starting
8
designing the base class because I wouldn’t need to plan for actual
objects of the class, but only for data and functions that would be used
Polymorphism
CGenericShape *next ;
public:
Polymorphism
CGenericShape *nextShape)
Polymorphism
:CGenericShape(x_in,y_in,nextShape){
x2=x2_in;
y2=y2_in;
}
void draw(HDC hdc){ // virtual draw function
MoveToEx(hdc,x,y,(LPPOINT) NULL);
LineTo(hdc,x2,y2); }
};
Object Oriented Programming 321
class CRectangle:public CLine{ // Rectangle class
public:
CRectangle (int x_in,int y_in,int x2_in,int y2_in,
CGenericShape *nextShape)
8
:CLine(x_in,y_in,x2_in,y2_in,nextShape)
Polymorphism
{}
void draw(HDC hdc){// virtual draw
Rectangle(hdc,x,y,x2,y2);
}
};
CGenericShape *nextShape)
Polymorphism
:CGenericShape(x_cen,y_cen,nextShape)
{
radius=r;
}
void draw(HDC hdc) { // virtual draw
Ellipse(hdc,x-radius,y-radius,x+radius,y+radius);
}
};
Object Oriented Programming 323
void ShowShapes(CGenericShape &shape,HDC hdc)
{
CGenericShape *p = &shape ;
8
while (p!=NULL){
p->draw(hdc); // It 's unknown at compile-time
p = ++*p ;
Sleep(100);
}
}
CCircle Circle1(100,100,20,&Line2);
CCircle Circle2(100,100,50,&Circle1);
Polymorphism
CRectangle Rectangle1(50,50,150,150,&Circle2);
switch (message) {
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
ShowShapes (Rectangle1,hdc);
EndPaint (hwnd, &ps);
return 0;
Object Oriented Programming 325
A
A Finite
Finite State
State Machine
Machine (FSM)
(FSM) Example
Example
State :{1, 2,3}
Input : { a, b }, x to exit
Output : { x , y }
8
a/y
Polymorphism
b/y
b/x
1 2
a/y a/x
b/x States of the FSM are defined using
3
a class structure.
Each state is derived from the same
base class.
Object Oriented Programming 326
class State { / / Base State (Abstract Class)
protected:
State * const next_a, * const next_b; / / Pointers to next state
char output;
public:
State(State & a, State & b):next_a(&a), next_b(&b) { }
virtual State* transition(char)= 0; / / pure virtual function
};
8
switch(input){
case 'a': output = 'y';
return next_a;
case 'b': output = 'x';
return next_b;
default : cout < < endl < < "Undefined input";
cout < < endl < < "Next State: Unchanged";
return this;
}
}
Object Oriented Programming 328
The FSM in our example has three states.
class FSM{ / / Finite State Machine
State1 s1;
State2 s2;
State3 s3;
State * current; / / points to the current state
public:
FSM() : s1(s1,s2), s2(s3,s2), s3(s1,s2), current(&s1) { } / / Starting state is State1
8
void run();
};
Polymorphism
void FSM::run() {
char in;
do {
cout < < endl < < "Give the input value (a or b; x: EXI T) ";
cin > > in;
if (in != 'x')
current = current-> transition( in) ; / / Polymorphic function call
else
curent = 0; / / EXI T
} while(current);
}
The transition function of the current state is called.
Return value of this function determines the next state of the FSM.
Object Oriented Programming 329
Virtual
Virtual Constructors?
Constructors?
►Can constructors be virtual?
No, they can’t be.
►When you’re creating an object, you usually already know
8
what kind of object you’re creating and can specify this to the
Polymorphism
are called.
public:
~Derv() { cout << "\nDerived destructor"; }
};
int main(){
Base pb = new Derived;
Base* ed
delete pb;
cout << endl << "Program terminates.“ << endl ;
}
Object Oriented Programming 332
Virtual
Virtual Destructors
Destructors
►But the output is
Base Destructor
Program terminates
►In this program bp is a pointer of Base type. So it can
point to objects of Base type and Derived type. In the
8
public:
~Derv() { cout << "\nDerived destructor"; }
};
int main(){
Base pb = new Derived;
Base* ed
delete pb;
cout << endl << "Program terminates.“ << endl ;
}
Object Oriented Programming 334
9 EXCEPTION
335
Program
Program Errors
Errors
►Kinds of errors with programs
– Poor logic - bad algorithm
– Improper syntax - bad implementation
9
program
Exception
– assert(pTruck);
Exception
user
// insert a disk)
}
catch(xNoMemory) {
// another exception handler for this “try block”
}
int *pData;
public:
...
class xBadIndex {}; // just like any other class
};
Object Oriented Programming 347
Throwing
Throwing An
An Exception
Exception
►In your code where you reach an error node:
if(memberIndex < 0)
throw xBadIndex();
9
Exception
calling function
►Exception handling uses it to find a catch block
catch blocks
Exception
catch (Set::xBadData) {
Exception
catch (Set::xBadData)
Exception
xBadIndex
xNegative xTooLarge
int badIndex;
Exception
public:
xBadIndex(int iType):badIndex(iType) {}
int GetBadIndex () { return badIndex; }
~xBadIndex() {}
};
throw xBadIndex(index);
// index is ok
if (badIndex < 0 )
Exception
cout << “Set Index “ << badIndex << “ less than 0”;
else
cout << “Set Index “ << badIndex << “ too large”;
cout << endl;
}
throw xTooLarge(index);
// index is ok
cout << “Set Index “ << badIndex << “ less than 0”;
Exception
template
– declare the exception inside the template
private:
Exception
T *pType;
public:
Set();
T& operator[] (int index) const;
};
T *pType;
public:
Exception
catch (Set<int>::xEachException)
Exception
class Zerodivide{/*..*/};
Exception
};
Exception
class D: public A {
public:
void f() throw (DerivedEx); //OK
void g() throw (OtherEx); //error
void h() throw (DerivedEx); //OK
void i() throw (BaseEx); //error
void j() throw (BaseEx,OtherEx); //error
};
Object Oriented Programming 372
Concordance
Concordance of
of Exception
Exception Specification
Specification
An exception could belong to two groups:
void f(){
try {
/ / something
}
catch (Network_err& e) {
// ...
}
}
}
Exception
catch(File_system_err& e) {
/ / ...
}
}
}
The handler is invoked:
[1] If H is the same type as E.
[2] If H is an unambiguous public base of E.
[3] If H and E are pointer types and [1] or [2] holds for the
types to which they refer.
[4] If H is a reference and [1] or [2] holds for the type to
which H refers.
Object Oriented Programming 375
Resource
Resource Management
Management
When a function acquires a resource – that is, it opens a file,
allocates some memory from the free store, sets an access
control lock, etc., – it is often essential for the future running
of the system that the resource be properly released.
9
Exception
try { …
// use f use_file(“c:\\dat.txt”);
} …
catch (Ex e) { }
fclose(f) ; catch(SomeEx e){
throw e; }
} }
fclose(f) ;
}
Object Oriented Programming 377
Resource
Resource Management
Management
The problem with this solution is that it is verbose, tedious,
and potentially expensive.
class File_ptr {
FILE* p;
9
public:
Exception
logic_error
9
Exception
runtime_error
9
Exception
{
public:
overflow_error(const string& what_arg)
: runtime_error(what_arg) {};
catch (exception& e)
{
cout << typeid(e).name() << “: “ << e.what() << endl;
}
class
– The handler gets a reference to exception as an
argument, so it can look at the object
object of that type, and returns its address, which gets assigned to a
base class pointer.
Exception
pointer.
► typeid operator
Exception
name
Exception
if(typeid(*carType) == typeid(Ford))
cout << “This is a Ford” << endl;
// Ford
► So:
cout << typeid(e).name()
returns the name of the exception
► what() returns the character string specified in the throw statement for
the exception
Exception
};
Exception
public:
Exception
Array(void);
Array(int);
class eNegativeIndex{};
class eOutOfBounds{};
class eEmptyArray{};
T& operator[](int) ;
};
}
Exception
}
catch(Array<int>::eNegativeIndex){
cout << "Negative Array" ;
}
catch(Array<int>::eOutOfBounds){
cout << "Out of bounds" ;
}
401
Kalıp-Parametrik Çok Şekillilik
Kalıp-Parametrik Çok Şekillilik Nedir?
Nedir?
Sınıflardaki fonksiyonların gövdeleri incelendiğinde, yapılan işlemler
çoğu zaman, üzerinde işlem yapılan verinin tipinden bağımsızdır. Bu
durumda fonksiyonun gövdesi, verinin tipi cinsinden, parametrik
olarak ifade edilebilir:
10
int abs(int n) {
Templates
return (n<0) ? -n : n;
}
long abs(long n) {
return (n<0) ? -n : n;
}
float abs(float n) {
return (n<0) ? -n : n;
}
Object Oriented Programming 402
►C
Her tip için farklı adlarda fonksiyonlar.
örnek mutlak değer fonksiyonları:
abs(), fabs(), fabsl(), labs(), cabs(), ...
10
► C++
Templates
int main(){
Templates
int i = 42;
std::cout << "max(7,i): " << ::max(7,i) << std::endl;
double f1 = 3.4;
double f2 = -6.7;
std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;
std::string s1 = "mathematics"; std::string s2 = "math";
std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}
max<double>(4,4.2) // Tamam
max(static_cast<double>(4),4.2) // Tamam
10
Templates
printArray a,3)
printArray( ;
printArray b,5)
printArray( ;
printArray c,7)
printArray( ;
return 0 ;
}
}
Templates
void printArray(char
printArray *array,cont int size){
for(int i=0;i < size;i++)
cout << array[i] << "" ;
cout << endl ;
}
int intVar1 = 5;
};
bool TComplex::operator>(const TComplex& z) const {
float norm1 = real * real + imag * imag;
float norm2 = z.real * z.real + z.imag * z.imag;
if (norm1 > norm2) return true;
else return false;
}
int main(){
int i1=5, i2= -3;
Templates
if(array[j]==value) return j;
return -1;
Templates
cout << "\n 'f' in chrArray: index=" << find(chrArr, ch, 6);
cout << "\n 6 in intArray: index=" << find(intArr, in, 6);
Templates
}
Templates
strcpy(temp,s1);
strcpy(s1,s2);
Templates
strcpy(s2,temp);
delete []temp;
}
...
swap( str1 , str2 ) ;
Templates
if(array[j]==value) return j;
return (btype)-1;
Templates
}
►Bu durumda, derleyici sadece farklı dizi tipleri için değil aynı
zamanda aranan elemanın farklı tipte olması durumunda da farklı bir
kod üretecektir:
short int result,si=100;
int invalue=5;
result = find(intArr, invalue,si) ;
};
class LongStack {
long st[MAX]; // array of longs
int top; // index number of top of stack
public:
LongStack(); // constructor
void push(long var); // takes long as argument
long pop(); // returns long value
};
Object Oriented Programming 420
template <class Type,int maxSize>
class Stack{
Type st[maxSize]; // stack: array of any type
int top; // number of top of stack
public:
Stack(){top = 0;} // constructor
10
};
template<class Type>
void Stack<Type>::push(Type var) // put number on stack
{
if(top > maxSize-1) // if stack full,
throw "Stack is full!"; // throw exception
st[top++] = var;
}
int main() {
Templates
►Compile-time Polymorphism
Templates
– templates
int main()
Templates
{
Line l;
Circle c, c1, c2;
…
};
Templates
int main()
{
Line l;
Circle c, c1, c2;
myDraw(l); // myDraw<Line>(GeoObj&)=>Line::draw()
myDraw(c); // myDraw<Circle>(GeoObj&)=>Circle::draw()
434
Standard
Standard Template
Template Library
Library
Nesneye dayalı programlamada, verinin birincil öneme sahip
programlama birimi olduğunu belirtmiştik. Veri, fiziksel yada soyut bir
Generic Programming 11
k
(sıralama,int,array)
veri tipi : int, float, ...
(sıralama,double,list)
(sıralama,int,list)
... template j
(sıralama,array) kap :
(sıralama,list) dizi, liste, kuyruk ...
algoritma :
... generic prog. i sıralama, kaynaştırma, arama ...
(sıralama)
Algoritma
• Kap (Container): nesneleri depolamak ve yönetmekten
sorumlu nesne,
• Lineer Kaplar : Vector, Deque, List
• Asosyatif Kaplar : Set, Map, Multi-set, Multi-map
• Yineleyici (Iterator): algoritmanın farklı tipte kaplarla
çalışmasını sağlayacak şekilde erişimin soyutlar.
düşünülebilir. deque kabı her iki uçtan veri eklemeye ve silmeye olanak sağlamaktadır.
Vector Relocating,
expandable array Quick random access (by index number).
Slow to insert or erase in the middle.
Quick to insert or erase at end.
► vector::iterator vector::begin()
► vector::iterator vector::end()
► vector::clear()
► bool vector::empty()
► vector::iterator vector::erase()
– erase(pos)
– erase(first,beyond)
– vector::iterator insert(pos,first,beyond)
– vector::iterator insert(pos,n,value)
► void vector::pop_back()
► void vector::push_back(value)
► vector::resize()
– resize(n,value)
► vector::swap()
– vector<int> v1(7),v2(10) ;
– v1.swap(v2);
► unsigned vector::size()
v.insert(v.end(),3) ; v = (3)
cout << v.capacity() << v.size() ;
v.insert (v.begin(), 2, 5); v = (5,5,3)
w.erase(w.begin()); w = (5,3)
w.erase(w.begin(),w.end()) ;
cout << w.empty() ? “Empty” : “not Empty” Empty
Object Oriented Programming 444
#define __USE_STL
// STL include files
Generic Programming 11
#include <vector>
#include <list>
vector<int> v;
v.insert(v.end(),3) ; v = (3)
v.insert(v.begin(),5) ; v = (5,3)
cout << v.front() << endl; 5
cout << v.back() ; 3
v.pop_back();
cout << v.back() ; 5
► Kurucular
– Boş: list<string> object;
– Belirli sayıda eleman:
• list<string> object(5,string(“hello”)) ;
• list<string> container(10)
• list<string> object(&container[5], &container[9]);
• list<string> object(container) ;
► list::iterator list::begin()
► list::iterator list::end()
► list::clear()
► bool list::empty()
► list::iterator list::erase()
– erase(pos)
– erase(first,beyond)
– list::iterator insert(pos,first,beyond)
– list::iterator insert(pos,n,value)
► void list::pop_back()
► void list::push_back(value)
► list::resize()
– resize(n,value)
► void list<type>::merge(list<type> other)
► void list<type>::remove(value)
► unsigned list::size() list1.cpp
list2.cpp
►Kurucular
– Boş: queue<string> object;
– Kopya Kurucu: queue<string> object(container) ;
priqueue1.cpp
priqueue2.cpp
►deque<string> object
• deque<string> object(5,string(“hello”)) ;
• deque<string> container(10)
• deque<string> object(&container[5], &container[9]);
• deque<string> object(container) ;
► deque::iterator deque::begin()
► deque::iterator deque::end()
► deque::clear()
► bool deque::empty()
► deque::iterator deque::erase()
– erase(pos)
– erase(first,beyond)
– deque::iterator insert(pos,value)
– deque::iterator insert(pos,first,beyond)
– deque::iterator insert(pos,n,value)
► void deque::pop_back()
► void deque::push_back(value)
► deque::resize()
– resize(n,value)
► deque::swap()
► unsigned deque::size()
► map<string,int> object
• pair<string,int>
pa[]= {
pair<string,int>(“one”,1),
pair<string,int>(“two”,2),
pair<string,int>(“three”,3),
pair<string,int>(“four”,4)
};
• map<string,int> object(&pa[0],&pa[3]);
► object[“two”]
– pair<map::iterator,bool> insert(pos,keyvalue)
– void insert(first,beyond)
► map::iterator map::lower_bound(key)
► map::iterator map::upper_bound(key)
► pair<map::iterator,map::iterator> map::equal_range(key)
► map::iterator map::find(key)
– returns map::end() if not found
► unsigned deque::size()
►map::clear()
►bool map::empty()
►map::iterator map::erase()
– erase(keyvalue)
– erase(pos)
– erase(first,beyond)
...
string city_name;
cout << "\nEnter a city: ";
cin >> city_name;
if (city_num.end()== city_num.find(city_name))
cout << city_name << " is not in the database" << endl;
else
cout << "Number of " << city_name << ": " << city_num[city_name];
}
Object Oriented Programming 464
MultiMap
MultiMap
►#include <map>
►Main difference between map and multimap is that the
Generic Programming 11
a.max_size()
a.empty() a.size() == 0
İİşşlleem Uyygguullaannaabbiillddiiğğii
U
m Döönnüüşş D
D Deeğğeerrii Yüürrüüttüülleenn İİşşlleem
Y m K
Kaappllaarr
a.front() T& *a.begin() vector, list, deque
a.back() T& *a.end() vector, list, deque
a.push_front(x) void a.insert(a.begin(),x) list,deque
a.push_back(x) void a.insert(a.end(),x) vector, list,deque
a.pop_front() void a.erase(a.begin()) list,deque
a.pop_back() void a.erase(--a.end()) list,deque
a[n] T& *(a.begin()+n) vector,deque
OutputIterator r;
InputIterator r; INPUT OUTPUT
Iterators Iterators
ForwardIterator r;
BidirectionalIterator r;
RandomIterator r ;
n OutputIterator a ; p OutputIterator r ;
Generic Programming 11
… …
*a=t ; r++ ;
t = *a ; Hata r++ ; Hata
range[v.begin(),v.end()]
list<int> l (1,1) ;
l.push_back(2) ; // list l : 1 2
list<int>::iterator first=l.begin() ;
list<int>::iterator last=l.end() ;
while( last != first){
-- last ;
cout << *last << “ ” ;
}
Object Oriented Programming 470
template<class ForwardIterator, class T>
ForwardIterator find_linear(ForwardIterator first,
Generic Programming 11
vector<int> v(3,1) ;
v.push_back(7); // vector : 1 1 1 7
vector<int>::iterator i=find_linear(v.begin(), v.end(),7) ;
if(i != v.end() ) cout << *i ;
else cout << “not found!” ;
vector<int>::iterator j=i+2;
cout << *j << “ ” ;
i += 3 ; cout << *i << “” ;
j = i – 1 ; cout << *j << “” ;
j -= 2 ; cout << *j << “” ;
cout << v[1] << endl ;
(j<i) ? cout << “j < i” : cout << “not j < i” ; cout << endl ;
(j>i) ? cout << “j > i” : cout << “not j > i” ; cout << endl ;
(j>=i) && (j<=i)? cout << “j and i equal” : cout << “j and i not equal > i” ; cout <<
endl ;
i=j;
j= v.begin();
i = v.end ;
cout << “iterator distance end – begin : ” << (i-j) ;
Object Oriented Programming 473
Iterator
Iterator Operators
Operators
►STL provides two functions that return the number of
elements between two elements and that jump from one
Generic Programming 11
template<class RandomAccessIterator>
iterator_traits<RandomAccessIterator>::difference_type
distance(RandomAccessIterator first, RandomAccessIterator
last) {
return last – first;
}
template<class InputIterator>
iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last) {
iterator_traits<InputIterator>::difference_type n = 0;
while (first++ != last) ++n;
return n;
}
Object Oriented Programming 475
advance()
advance()
►So far, we have seen how we can move iterators forward
and backward by using the increment and decrement
Generic Programming 11
template<class T>
Generic Programming 11
template<class T>
Generic Programming 11
#include <iostream>
#include <algorithm> //for count()
int arr[] = { 33, 22, 33, 44, 33, 55, 66, 77 };
int main(){
int n = count(arr, arr+8, 33); //count number of 33’s
cout << “There are “ << n << ” 33’s in arr.” << endl;
return 0;
}
#include <vector>
#include <algorithm> //for count_if()
int a[] = { 1, 2, 3, 4, 3, 4, 2, 1, 3 };
class Odd {
public:
bool operator()(int val){ return val&1 ; }
};
int main(){
std::vector<int> iv(a,a+9) ;
std::cout << count_if(iv.begin(),iv.end(),Odd()) ;
return 0 ;
}
Object Oriented Programming 487
equal()
equal()
►bool equal(InputIterator first, InputIterator last,
InputIterator otherFirst)
Generic Programming 11
}
};
int main(){
string
first[]={"Alpha","bravo","Charley","echo","Delta","golf"},
second[]={"alpha","Bravo","charley","Echo","delta","Golf"} ;
std::string *last = first + sizeof(first)/sizeof(std::string) ;
cout << (equal(first,last,second)?"Equal":"Not equal") ;
cout << (equal(first,last,second,CaseString())?"Equal":
"Not equal") ;
return 0 ;
}
Object Oriented Programming 489
fill(),fill_n()
fill(),fill_n()
►void fill(ForwardIterator first,ForwardIterator last,
Type const &value)
Generic Programming 11
vector<int> iv(8) ;
fill(iv.begin(),iv.end(),8) ;
vector<int> iv(8) ;
fill_n(iv.begin()+2,4,8) ;
#include <iostream>
#include <algorithm>
int arr[] = {45, 2, 22, -17, 0, -30, 25, 55};
int main(){
sort(arr, arr+8); //sort the numbers
for(int j=0; j<8; j++) //display sorted array
cout << arr[j] << ‘ ‘;
return 0;
}
Object Oriented Programming 491
search()
search()
► Some algorithms operate on two containers at once. For instance,
while the find() algorithm looks for a specified value in a single
container, the search() algorithm looks for a sequence of values,
Generic Programming 11
int source[] = { 11, 44, 33, 11, 22, 33, 11, 22, 44 };
int pattern[] = { 11, 22, 33 };
int main(){
int* ptr;
ptr = search(source, source+9, pattern, pattern+3);
if(ptr == source+9) cout << “No match found\n”;
else cout << “Match at ” << (ptr - source) ;
return 0;
}
Object Oriented Programming 492
binary_search()
binary_search()
► #include <algorithm>
– bool binary_search(ForwardIterator first, ForwardIterator last,Type const
&value)
Generic Programming 11
int main(){
int ia[]={1,2,3,4} ;
std::vector<int> iv(ia,ia+4) ;
int ia[]={1,3,7,23} ;
std::vector<int> iv(ia,ia+4) ;
std::vector<int> ov(iv.size()) ;
adjacent_difference(iv.begin(),iv.end(),ov.begin()) ;
copy(ov.begin(),ov.end(),std::ostream_iterator<int>(cout," ")) ;
std::cout << std::endl ;
adjacent_difference(iv.begin(),iv.end(),ov.begin(),minus<int>()) ;
copy(ov.begin(),ov.end(),ostream_iterator<int>(cout," ")) ;
system("pause") ;
return 0 ;
}
Object Oriented Programming 498
copy(),
copy(), copy_backward()
copy_backward()
► #include <algorithm>
– OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator destination)
Generic Programming 11
tmp[0] = toupper(*tmp) ;
std::cout << tmp << " " ;
delete []tmp; foreach1.cpp
}
Object Oriented Programming 500
int main(){
std::string
sarr[] =
{
Generic Programming 11
} }
int main(){
int iArr[] = { 5,2,23,76,33,44} ;
std::for_each(iArr,iArr+6,show) ; std::cout << std::endl ;
std::transform(iArr,iArr+6,iArr,_3_n_plus_1) ;
std::for_each(iArr,iArr+6,show) ;
system("pause") ;
return 0 ;
}
transform.cpp
template<class T>
class equal_to : binary_function<T, T, bool> {
bool operator()(T& arg1, T& arg2) const { return arg1 == arg2; }
};
507
Streams
Streams
►A stream is a general name given to a flow of data in an
input/output situation. For this reason, streams in C++ are
often called iostreams.
iostreams
►An iostream can be represented by an object of a
Streams 12
particular class.
►For example, you’ve already seen numerous examples of
the cin and cout stream objects used for input and output.
fstream
used.
>>
get(ch) Extract one character into ch.
get(str) Extract characters into array str, until ‘\0’.
get(str, MAX) Extract up to MAX characters into array.
get(str, DELIM) Extract characters into array str until specified delimiter
(typically ‘\n’).
Leave delimiting char in stream.
write(str, SIZE) Insert SIZE characters from array str into file.
seekp(position) Sets distance in bytes of file pointer from start of file.
seekp(position, seek_dir) Set distance in bytes of file pointer from specified place in
file. seek_dir can be ios::beg, ios::cur, or ios::end.
position = tellp() Return position of file pointer, in bytes.
The cerr object is often used for error messages and program diagnostics. Output
Streams 12
sent to cerr is displayed immediately, rather than being buffered, as output sent
to cout is. Also, output to cerr cannot be redirected. For these reasons, you have
a better chance of seeing a final output message from cerr if your program dies
prematurely. Another object, clog, is similar to cerr in that it is not redirected,
but its output is buffered, whereas cerr’s is not.
Stream Errors
What happens if a user enters the string “nine” instead of the integer 9, or pushes
ENTER without entering anything? What happens if there’s a hardware failure?
We’ll explore such problems in this session. Many of the techniques you’ll see here
are applicable to file I/O as well.
Various ios functions can be used to read (and even set) these error bits.
int = eof(); Returns true if EOF bit set.
int = fail(); Returns true if fail bit or bad bit or hard-fail bit set.
int = bad(); Returns true if bad bit or hard-fail bit set.
int = good(); Returns true if everything OK; no bits set.
clear(int=0); With no argument, clears all error bits;
otherwise sets specified bits, as in clear(ios::failbit).
// no error
}
// error
Now if the user types without any digits, failbit will be set and an
error will be generated. The program can then tell the user what to
do or reposition the cursor so the screen does not scroll.
When the program terminates, the outfile object goes out of scope. This calls its
destructor, which closes the file, so you don’t need to close the file explicitly.
You must separate numbers (such as 77 and 6.02) with nonnumeric characters. Because
numbers are stored as a sequence of characters rather than as a fixed-length field, this is
the only way the extraction operator will know, when the data is read back from the file,
where one number stops and the next one begins. Second, strings must be separated with
whitespace for the same reason. This implies that strings cannot contain embedded
blanks. In this example, I use the space character (“ “) for both kinds of delimiters.
Characters need no delimiters, because they have a fixed length.
char str1[MAX];
char str2[MAX];
ifstream infile("fdata.txt"); // create ifstream object
infile >> ch >> j >> d >> str1 >> str2; // extract data from it
cout << ch << endl // display the data
<< j << endl
<< d << endl
<< str1 << endl
<< str2 << endl;
}
Object Oriented Programming 535
Detecting
Detecting End-OF-File
End-OF-File
► Objects derived from ios contain error-status bits that can be
checked to determine the results of operations. When you read a file
little by little, you will eventually encounter an end-of-file condition.
The EOF is a signal sent to the program from the hardware when there
Streams 12
requiring 10 bytes.
The next example shows how an array of integers is written to disk and then
read back into memory using binary format. I use two new functions: write(),
a member of ofstream, and read(), a member of ifstream. These functions
think about data in terms of bytes (type char). They don’t care how the data is
formatted, they simply transfer a buffer full of bytes from and to a disk file.
The parameters to write() and read() are the address of the data buffer and its
length. The address must be cast to type char, and the length is the length in
bytes (characters), not the number of data items in the buffer.
protected:
char name[40]; // person's name
int age; // person's age
public:
void getData(void) { // get person's data
std::cout << "Enter name: "; cin >> name;
std::cout << "Enter age: "; cin >> age;
}
};
on the same class of objects. Objects of class person in these programs are exactly
42 bytes long, with the first 40 occupied by a string representing the person’s name
and the last 2 containing an int representing the person’s age.
Notice, however, that although the person classes in both programs have the same
data, they may have different member functions. The first includes the single
function getData(), whereas the second has only showData(). It doesn’t matter
what member functions you use, because members functions are not written to disk
along with the object’s data. The data must have the same format, but
inconsistencies in the member functions have no effect. This is true only in simple
classes that don’t use virtual functions.
public:
void getData() { // get person's data
cout << "\n Enter name: "; cin >> name;
cout << " Enter age: "; cin >> age;
}
void showData() { // display person's data
cout << "\n Name: " << name;
cout << "\n Age: " << age;
}
};
Object Oriented Programming 543
int main(){
objfile.cpp
char ch;
person pers; // create person object
fstream file; // create input/output file
file.open("PERSON.DAT", ios::out | ios::binary ); // open for append
do{ // data from user to file
cout << "\nEnter person's data:";
pers.getData(); // get one person's data
file.write( (char*)&pers, sizeof(pers) ); // write to file
Streams 12
Analyzing Errors
In the previous example, we determined whether an error occurred in an I/O
operation by examining the return value of the entire stream object.
if(!is)
// error occurred
However, it’s also possible, using the ios error-status bits, to find out more specific
information about a file I/O error.
Object Oriented Programming 546
#include <fstream.h> // for file functions
int main(){
ifstream file;
file.open("GROUP.DAT", ios::nocreate);
if( !file )
cout << endl <<"Can't open GROUP.DAT";
Streams 12
else
cout << endl << "File opened successfully.";
cout << endl << "file = " << file;
cout << endl << "Error state = " << file.rdstate();
cout << endl << "good() = " << file.good();
cout << endl << "eof() = " << file.eof();
cout << endl << "fail() = " << file.fail();
cout << endl << "bad() = " << file.bad();
file.close();
}
Object Oriented Programming 547
This program first checks the value of the object file. If its value is zero, the
file probably could not be opened because it didn’t exist. Here’s the output of
the program when that’s the case:
Can't open GROUP.DAT
file = 0x1c730000
Error state = 4
good() = 0
Streams 12
eof() = 0
fail() = 4
bad() = 4
The error state returned by rdstate() is 4. This is the bit that indicates the file
doesn’t exist; it’s set to 1. The other bits are all set to 0. The good() function
returns 1 (true) only when no bits are set, so it returns 0 (false). I’m not at
EOF, so eof() returns 0. The fail() and bad() functions return nonzero because
an error occurred.
In a serious program, some or all of these functions should be used after every
I/O operation to ensure that things have gone as expected.
Object Oriented Programming 548
File
File Pointers
Pointers
Each file object has associated with it two integer values called the get pointer and the put
pointer. These are also called the current get position and the current put position, or—if it’s
clear which one is meant—simply the current position. These values specify the byte number
in the file where writing or reading will take place
There are times when you must take control of the file pointers yourself so that you can read
from or write to an arbitrary location in the file. The seekg() and tellg() functions allow you to
Streams 12
set and examine the get pointer, and the seekp() and tellp() functions perform the same actions
on the put pointer.
// seeks particular person in file
#include <fstream.h> // for file streams
class person { // class of persons
protected:
char name[40]; // person's name
int age; // person's age
public:
void showData() { // display person's data
cout << "\n Name: " << name; cout << "\n Age: " << age;
}
};
Object Oriented Programming 549
int main(){
person pers; // create person object
ifstream infile; // create input file
infile.open("PERSON.DAT", ios::binary); // open file
infile.seekg(0, ios::end); // go to 0 bytes from end
int endposition = infile.tellg(); // find where we are
int n = endposition / sizeof(person); // number of persons
cout << endl << "There are " << n << " persons in file";
Streams 12
cout << endl << "Enter person number: "; cin >> n;
int position = (n-1) * sizeof(person); // number times size
infile.seekg(position); // bytes from begin
infile.read( (char*)&pers, sizeof(pers) ); // read one person
pers.showData(); // display the person
}
Here’s the output from the program, assuming that the PERSON.DAT file
contains 3 persons:
There are 3 persons in file
Enter person number: 2
Name: Rainier
Age: 21
Object Oriented Programming 550
File
File I/O
I/O Using
Using Member
Member Functions
Functions
So far, we’ve let the main() function handle the details of file I/O. This
is nice for demonstrations, but in real object-oriented programs, it’s
natural to include file I/O operations as member functions of the class.
cout << "\n Name: " << name; cout << "\n Age: " << age; }
void diskIn(int ); // read from file
void diskOut(); // write to file
static int diskCount(); // return number of persons in file
};
void person::diskIn(int pn){ // read person number pn from file
ifstream infile; // make stream
infile.open("PERSON.DAT", ios::binary); // open it
infile.seekg( pn*sizeof(person) ); // move file ptr
infile.read( (char*)this, sizeof(*this) ); // read one person
}
Object Oriented Programming 552
void person::diskOut() // write person to end of file
{
ofstream outfile; // make stream
outfile.open("PERSON.DAT", ios::app | ios::binary); // open it
outfile.write( (char*)this, sizeof(*this) ); // write to it
}
Streams 12
and keyboard (cout and cin). With a little more care, you can also overload them so they
work with disk files as well.
#include<iostream>
class TComplex {
float real,img;
friend std::istream& operator >>(std::istream&, TComplex&);
friend std::ostream& operator <<(std::ostream&, const TComplex&);
public:
TComplex(float rl=0,float ig=0){real=rl;img=ig;}
TComplex operator+(const TComplex&);
};
Object Oriented Programming 555
istream& operator >>(istream& stream, TComplex& z){ // Overloading >>
cout << "Enter real part:";
stream >> z.real;
cout << "Enter imaginer part:";
stream >> z.img;
return stream;
}
ostream& operator <<(ostream& stream, const TComplex & z){
stream << "( " << z.real << " , " << z.img << " ) \n";
Streams 12
return stream;
}
TComplex TComplex::operator+(const TComplex & z){ // Operator +
return TComplex (real+z.real , img+z.img);
}
int main(){
TComplex z1,z2,z3;
std::cin >> z1;
std::cin >> z2;
z3=z1+z2;
std::cout << " Result=" << z3; inout.cpp
}
Object Oriented Programming 556
Overloading
Overloading for
for Files
Files
The next example shows how the << and >> operators can be overloaded so they
work with both file I/O and cout and cin.
#include<fstream>
class TComplex {
float real,img;
friend istream& operator >>(istream&, TComplex&);
Streams 12
protected:
char name[40]; // person's name
int age; // person's age
public:
void getData(){ // get data from keyboard
cout << "\n Enter name: "; cin.getline(name, 40);
cout << " Enter age: "; cin >> age;
}
void putData(){ // display data on screen
cout << "\n Name = " << name; cout << "\n Age = " << age;
}
friend istream& operator >> (istream& s, person& d);
friend ostream& operator << (ostream& s, person& d);
Object Oriented Programming 559
void persin(istream& s){
s.read( (char*)this, sizeof(*this) );
}
void persout(ostream& s) // write our data to file
{
s.write( (char*)this, sizeof(*this) );
}
Streams 12