Object Oriented Programming with C++

parentpitaSoftware and s/w Development

Nov 18, 2013 (3 years and 7 months ago)

142 views

(c) CTI, Christian V. Madritsch 1
FH-Prof. Christian V. Madritsch
Systems Design
www.cti.ac.at/rts
Object Oriented
Programming with C++
5/29/2013 2cm@cti.ac.at
Copyright Notice

All rights reserved. No part of this publication
may be reproduced, stored in a retrieval system
or transmitted, in any form or by any means,
electronic, mechanical, photocopying, recording,
or otherwise, without prior written permission of
the author except for student usage.

Copyright © 2009 by Christian V. Madritsch
Tron, 1982, Buena Vista Pictures
(c) CTI, Christian V. Madritsch 2
5/29/2013 3cm@cti.ac.at
Contents

Object Oriented Programming

Classes

Principles of OOP

Encapsulation

Inheritance

Polymorphism

C++ Specifics
5/29/2013 4cm@cti.ac.at
Bibliography

OOP Demystified

Jim Keogh and Mario Giannini

Verlag: McGraw-Hill

ISBN: 0072253630

C++ Demystified

Jeff Kent

Verlag: McGraw-Hill

ISBN: 0072253703

UML Demystified

Paul Kimmel

Verlag: McGraw-Hill

ISBN: 007226182X

C++ How To Program

H.M.Deitel, P.J. Deitel

Verlag: Prentice Hall

ISBN: 0-13-117334-0
(c) CTI, Christian V. Madritsch 3
5/29/2013 5cm@cti.ac.at
History (i)

Procedural Programming

C, Ada, Pascal, Fortran, ...

Functions, which encapsulate
functional entities

An insufficient representation of the real world

Object-oriented Programming

C++, Simula, Smalltalk, ...

Objects encapsulate both, Data and Functions

C++ was developed in the 80s by Prof. Bjarne Stroustrup

Stroustrup decided, to implement C++ compatible to C:

C++ and C can be mixed

C++ can be seen as an extension of C
29.05.2013 6cm@cti.ac.at
History (ii)
(c) CTI, Christian V. Madritsch 4
5/29/2013 7cm@cti.ac.at
Fundamental Principles of OOP
Information Hiding
Data Encapsulation
Inheritance
Data Abstraction
Polymorphism*
Reusability
5/29/2013 8cm@cti.ac.at
Fundamental Principles of OOP

Data Encapsulation:

Shielding of an object and its methods to the outside.

Encapsulation allows the protection of data and
methods of a class against an access from outside,
e.g. by another object.

Information Hiding
:

Each program module should disclose as little as
possible about its internal workings.
(c) CTI, Christian V. Madritsch 5
5/29/2013 9cm@cti.ac.at
Fundamental Principles of OOP

Inheritance:

Is the ability of an object, to inherit data and
methods automatically from another object
.

Single Inheritance

Multiple inheritance

The inheriting class is called base class, the inherited
class is called derived class.
5/29/2013 10cm@cti.ac.at
Fundamental Principles of OOP

Polymorphism:

Is the ability such that different objects can react on the
same method in different ways.

In C++, objects used through their base class pointer react as if
they were used through their derived class pointer.

Those pointers can change during runtime.

The compiler cannot decide at compile time which object is
bound to which method call.

dynamic binding, late binding
(c) CTI, Christian V. Madritsch 6
5/29/2013 11cm@cti.ac.at
The world is made of objects (i)

„The world is made of objects"

A house is an object.

The things in a house are objects.

Things we throw away are objects.

We are objects.
5/29/2013 12cm@cti.ac.at
The world is made of objects (ii)

What is an object?

Subjects

Car, Bank Accounts, …

Roles

Chauffeurs, Members, …

Events

tour, calculation, …

Interaction

Leasing contract, cash withdrawl

Specifications

Describing properties

What describes an object?

Data and properties

Methods describe the behaviour and the interacitvity
(c) CTI, Christian V. Madritsch 7
5/29/2013 13cm@cti.ac.at
The world is made of objects (iii)

Abstract Objects

Describes general data and methods of an object

Person: Age, Size, Name, walking, standing, driving

Object: Person

Data, Properties: age, size, weight, name, ...

Methods: walking, standing, driving a car, ...

Real Objects

Are instances of real objects which consist of real data

Person Tom: 27, 182, Tom Jones, walking
5/29/2013 14cm@cti.ac.at
Development of C++ (i)

1980: C with classes

Classes (with private/public assess)

Single Inheritance (no virtual functions)

Constructor/Destructor

Operator Overloading

References

Friend Classes

Constants

1982: C with classes

Default Arguments

Overloading of the assignment operator

Inline-functions

1986: C++ 1.0 and 2.0

Multiple Inheritance

Abstract Classes

Static and constant member functions
(c) CTI, Christian V. Madritsch 8
5/29/2013 15cm@cti.ac.at
Development of C++ (ii)

1990: C++ 2.1

Virtual Functions

Exceptions

Templates

Improved IO (iostream)

1998: ISO/IEC 14882:1998 C++98

Run-Time Type Identification (RTTI)

static_cast, dynamic_cast

const_cast, reinterprete_cast

Namespace

2003: ISO/IEC 14882:2003 C++03

Mainly Bug fixes

2007: ISO/IEC TR 19768:2007 C++TR1

Standard Template Libraries

2011: ISO/IEC 14882:2011 C++11

Latest Edition
5/29/2013 16cm@cti.ac.at
Classes

A Class is a userdefined datatype which is based on struct.

Classes consist of Data and Methods
class RegistrationForm {
public:// Visibility
int studentNumber;// Data
int courseNumber;// Data
void dropCourse(int courseNumber, int studentNumber) { // Method
...
}
};

Methods can be programmed outside the class definition:
void RegistrationForm :: dropCourse(int courseNumber, int studentNumber)
{
...
}
(c) CTI, Christian V. Madritsch 9
5/29/2013 17cm@cti.ac.at
Constructor (i)

Data of a class can not be initialized directly

A constructor is a method which is called
automatically at creation time of the class
instance.

The constructors name is always the name of the class

A constructor must not have a return type

The only task of the constructor is to initialize data
5/29/2013 18cm@cti.ac.at
Constructor (ii)

There are three kinds of constructors:

Default constructor

Has no Parameters or only default values
– Is automatically generated by the compiler (if it does not exist)

... C++ automatically provides a default constructor, that
sets all the data members of the object to binary zero.

User defined Constructor(s)

Parameter list of the data to initialize

Copy Constructor

Constructors can be overloaded
(c) CTI, Christian V. Madritsch 10
5/29/2013 19cm@cti.ac.at
Default Constructor
class Student{
private:
int m_ID;
public:
Student(){m_ID = 0;}
};

How to use it:
Student student1; // OK
Student student2 = Student(); // OK
Student student3(); // ERROR
5/29/2013 20cm@cti.ac.at
Parameter Default Values

Assigned to often used end of list Parameters

Default parameters do not need to be specified at the call
void test_param(int x, int y = 1, int z = 2) {
cout << "x=" << x << ", y=" << y <<", z=" << z << endl;
}
...
test_param(10,20,30);
test_param(10,20);
test_param(47);
test_param(); // Invalid!
(c) CTI, Christian V. Madritsch 11
5/29/2013 21cm@cti.ac.at
User defined constructor
class Student{
private:
int m_ID;
public:
Student(int ID = 0){m_ID = ID;}
};

How to use it:
Student student1;// OK
Student student2(12345); // OK
Student student3 = Student(12345); // OK
5/29/2013 22cm@cti.ac.at
Destructor (i)

Before an instance of a class is being deleted, some cleanup
activities might be necessary.

Deallocate Dynamic Memory

Close Connections to Ressources

The destructor is a method which is called
automatically bevor the instance of a class is deleted.

Before the Instance Variable loses its validity

Before the delete operator is executed

The method name of the destructor is alsways:

~Classname
(c) CTI, Christian V. Madritsch 12
5/29/2013 23cm@cti.ac.at
Destructor (ii)

A destructor

Must not have a return type

Must not have a parameter list

Can not be overloaded

How to use it:
class
Student{
...
~Student(){
// Aktionen
}
...
5/29/2013 24cm@cti.ac.at
Class combined with a program
#include <iostream>
using namespace std;
class RegistrationForm {
public:// Visibility
int studentNumber;
int courseNumber;
void dropCourse(int courseNumber, int studentNumber) {
cout << "Student " << studentNumber << " dropped from course " << courseNumber;
}
};
int main(void)
{
RegistrationForm regForm; // Instance of the class
regForm.dropCourse(123, 456); // Class method call
return 0;
}

A class needs to be instantiated before its data and methods can be
used.

Compare: int i;
(c) CTI, Christian V. Madritsch 13
5/29/2013 25cm@cti.ac.at
Class Circle
class Circle{
private:
double radius;// Data
public:
Circle(double R){ radius = R;}// Constructor
double Area(){ return 3.14*radius*radius;}
double Circumference(){ return 2*3.14*radius;}
};
5/29/2013 26cm@cti.ac.at
Class Cuboid
class Cuboid{
private:
double a, b, c;// Data
public:
Cuboid(double A,double B,double C){ // Constructor
a = A; b = B; c = C;}
double volume(){ return a*b*c;}
double surface(){ return 2*(a*b + a*c + b*c);}
};
(c) CTI, Christian V. Madritsch 14
5/29/2013 27cm@cti.ac.at
Class Fahrenheit
class Fahrenheit{
double celsius;// Degree Celsius
public:
Fahrenheit(double C){ celsius = C;}
double temperature(){ return 1.8*celsius+32;}
};
int main(void)
{
for(double x = 0; x <= 100; x += 10){
Fahrenheit f(x);
cout << x << " " << f.temperature() << endl;
}
return 0;
}
5/29/2013 28cm@cti.ac.at
Class Fraction
class Fraction{
private:
int numerator;
int denominator;
public:
Fraction(int n=0, int d=1){ // Constructor with default parameters
numerator = n; denominator = d;}
double value(){ return numerator/double(denominator);}
int denominator(){ return denominator;}
};
int main(void)
{
Fraction a(3,5);
Fraction b(3);
a.numerator = -2; // Error!
b.denominator = 7; // Error!
cout << b.numerator << endl;// Error!
cout << „Value of a = " << a.value() << endl;
cout << „denominator of b = " << b.denominator() << endl;
return 0;
}
(c) CTI, Christian V. Madritsch 15
5/29/2013 29cm@cti.ac.at
Class Fraction: Copy-construktor
class Fraction{
private:
int numerator;
int denominator;
...
};
int main(void)
{
Fraction b(3);
Fraction c = b; // Call of the Copy Constructor
...
}

The copy constructor creates a new object by elementwise copy
of the source object.

The copy constructor is called:

If one object is explicitly initialized by an other object (see above)

At initialization of a formal parameter at call by value

Return of a method result
5/29/2013 30cm@cti.ac.at
Static components of a class

Data and Methods of a class can be
declared static using the keyword static

The corresponding components are class
specific and no more object specific

In the case of static data it means, that this
component will be stored only one time for all
instances of this class.
(c) CTI, Christian V. Madritsch 16
5/29/2013 31cm@cti.ac.at
Class Variables
class Vector {
public:
Vector ();
Vector (float, float);
~Vector ();
static int vz; // <<--- Declaration of static data
private:
float x, y;
};
int Vector::vz = 0; // <<--- Definition and initialization of s. data
Vector::Vector () {
x=0; y=0; ++vz; } // Constr. increments vz
Vector::~Vector () {
--vz; } // Destr. decrements vz
Vector::Vector (float a, float b) {
x=a; y=b; ++vz; } // Constr. increments vz

In this example a static data component is used to count the
number of objects of type class Vector
5/29/2013 32cm@cti.ac.at
How to use static
components?

In the case of „normal“ data, the following notation is
used:
Vector v; v.x=0; // x of Vector v to 0

In the case of class varibales, there exists no object which
owns the variable. The access notation uses the class
itself:
Vector::vz=0; // vz of Vector Class to 0

Like statis data, static funtions do not belong to a specific
instanze (Object) of the class; the belong to the class
itslef.

They are executed independent of any specific obeject.
(c) CTI, Christian V. Madritsch 17
5/29/2013 33cm@cti.ac.at
Static Methods
class Vector {
public:
Vector ();
Vector (float, float);
~Vector ();
static int HowMany(); // Declaration of static Method
private:
float x, y;
static int vz;
};
int Vector::vz = 0;
int Vector::HowMany() { return vz; } // Definition of static Method
void f () {
Vector v;
cout << v.HowMany() << endl; // Output: 3
}
int main () {
cout << Vector::HowMany() << endl; // Output: 0 Call of static Method
Vector v1, v2(1.0, 2.5);
cout << Vector::HowMany() << endl; // Output: 2
f();
cout << Vector::HowMany() << endl; // Output: 2
}
5/29/2013 34cm@cti.ac.at
Constant Components,
Constant Parameters

Components of a class can be declared constant using the
keyword const

Constant Data Components can not be modified
class Book {
public:
Book (string, string);
private:
string title, author;
const int regID; // constant Data component
static int nextID;
};

Constant class components can only be initialized using initializers
Book::Book(string p_author, string p_title)
: regID (nextID)// Initializer
{
author = p_author;
title = p_title;
++nextID;
}
(c) CTI, Christian V. Madritsch 18
5/29/2013 35cm@cti.ac.at
Constant Methods

A method can be declared as constant (similar to constant data elements).

The meaning is different: It means the Method does not change anything, it does not mean it can not
be changed.
class Vector {
public:
Vector ();
Vector (float, float);
float xValue () const; // Constant Method
float yValue () const; // Constant Method
private:
float x, y;
};
float Vector::xValue () const { return x; }
float Vector::yValue () const { return y; }

It is good C++ programming style to declare all data components private and if necessary
access them using Get/Set Methods

The Get Method should be constant
5/29/2013 36cm@cti.ac.at
Constant Parameters

The formal parameters of a method can be declared constant

The method means: I will not change these parameters

The promise not to change the parameters is only interesting, if a
change within the method would have consequences outside the
method.

This is only the case if call by reference (pointer) is used
Vevtor operator+ (const Vector *v1, const Vector *v2) {
return Vector (v1->xValue() + v2->xValue(),
v1->yValue() + v2->yValue());
}
(c) CTI, Christian V. Madritsch 19
5/29/2013 37cm@cti.ac.at
Constant Method with constant
Parameters
class Vector {
public:
Vector ();
Vector (float, float);
Vector operator+ (const Vector &v) const;
private:
float x, y;
};
Vector Vector::operator+ (const Vector &v) const {
return Vector (x+v.x, y+v.y);
}

The first const means that the right operand of the addition will not be
changed, the second const guaranteed, that the left operand of the addition
will not be changed
5/29/2013 38cm@cti.ac.at
Call by Reference (i)
#include <iostream>
using namespace std;
void doubleIt(int);
int main(void)
{ int num;
cout << "Enter number: ";
cin >> num;
doubleIt(num);
cout << "The number doubled in main is " << num << endl;
return 0;
}
void doubleIt(int x)
{
cout << "The number to be doubled is " << x << endl;
x *= 2;
cout << "The number doubled in doubleIt is " << x << endl;
}
(c) CTI, Christian V. Madritsch 20
5/29/2013 39cm@cti.ac.at
Call by Reference (ii)
#include <iostream>
using namespace std;
void doubleIt(int&);
int main(void)
{ int num;
cout << "Enter number: ";
cin >> num;
doubleIt(num);
cout << "The number doubled in main is " << num << endl;
return 0;
}
void doubleIt(int& x)
{
cout << "The number to be doubled is " << x << endl;
x *= 2;
cout << "The number doubled in doubleIt is " << x << endl;
}
29.05.2013 40cm@cti.ac.at
Encapsulation

Encapsulation connects Data and Methods into a
class.

Through visibility settings, the access to the data
and methods can be restricted.

private, public and protected

Default Visibility:

private

Class Methods have access to all other class
methods or data even if their visibility is private or
protected.
(c) CTI, Christian V. Madritsch 21
5/29/2013 41cm@cti.ac.at
public

Data and Methods of an instance can be used from
outside the class.
#include <iostream>
using namespace std;
class Student{
public:
void Display(void){
cout << "Statements go here." << endl;}
};
int main(void){
Student myStudent;
myStudent.Display();
return 0;
}
29.05.2013 42cm@cti.ac.at
private

Data and Methods of an instance cannot be used from
outside the class.
#include <iostream>
using namespace std;
class Student{
public:
void Display(void){
cout << "Student: " << m_ID << " " << m_First << endl;}
private:
int m_ID; char m_First[16];
};
int main(void){
Student myStudent;
myStudent.Display();
return 0;
}
(c) CTI, Christian V. Madritsch 22
5/29/2013 43cm@cti.ac.at
protected

The access to data and methods is only allowed by
methods of the class itself or methods of a derived class.
29.05.2013 44cm@cti.ac.at
Rules

Data:

Direct access from outside (public) is a dont't

Data are generally used as private (or protected).

Consequence:

The access from outside is done via methods (get/set).

Methods:

Only methods which are needed outside are public.

All other methods are declared private (or protected).

All public methods of a class are called the class interface.
(c) CTI, Christian V. Madritsch 23
29.05.2013 45cm@cti.ac.at
Class Point
class Point{
private:
double x,y;// cartesian coordinates
public:
Point(double X=0,double Y=0) {x = X; y = Y;}
void setx(double X) {x = X;}
void sety(double Y) {y = Y;}
double getx() {return x;}
double gety() {return y;}
void moveto(double X,double Y) {x = X; y = Y;}
};
int main(void){
Point A(3,1), B(6,-3);
cout << „Points given " << endl;
cout << "A = (" << A.getx() << "," << A.gety() << ")" << endl;
cout << "B = (" << B.getx() << "," << B.gety() << ")" << endl;
B.moveto(9,9);
cout << "B move to (" << B.getx() << "," << B.gety() << ")" << endl;
return 0;
}
29.05.2013 46cm@cti.ac.at
Friends (i)

C Functions or methods of other classes
cannot access private members of a class.

Using the Friend concept, this restriction can
be bypassed.

Classes may declare C Functions or other
classes as their freinds.

A friend has full access to all private members.
(c) CTI, Christian V. Madritsch 24
29.05.2013 47cm@cti.ac.at
Friends (ii)

C Functions as Friends

The class Vector declares the C Function void print(Vector) as their
friend:
class Vector {
friend void print (Vector);
public:
...
private:
float x, y;
};
void print (Vector v) {
cout << "(" << v.x << ", " << v.y << ")\n"; }
29.05.2013 48cm@cti.ac.at
Friends (iii)

Classes as Friends
class Vector {
friend class Point;
private:
float x, y;
};
class Point {
public:
float distance_from (Point);
private:
Vector pos;
};
float Point::distance_from (Point p) {
return sqrt((pos.x-p.pos.x)*(pos.x-p.pos.x)+
(pos.y-p.pos.y)*(pos.y-p.pos.y));
}
(c) CTI, Christian V. Madritsch 25
5/29/2013 49cm@cti.ac.at
Inheritance Basics

Inheritance allows one class to acquire properties
(data) and methods of an other class.

Inheritance is usable if two classes X, Y are in
the following relation:
X is a Y.

A mammal is an animal.

A fox is a mammal.

A wristwatch is a clock.
Inheritance Basics
29.05.2013 50cm@cti.ac.at
Localization
IServices
Gyro
App
Multiple- or Single
Inheritance to
extend functionality
USB
HDMI
Ethernet
RS232
INTERFACE
-open
-init

-close
abstract
(c) CTI, Christian V. Madritsch 26
29.05.2013 51cm@cti.ac.at
Example: Crafts
Craft
Aircraft
Balloon
Helicopter
Plane
Landcraft
Truck
Car
Rail
Watercraft
Sailboat
Tankship
Submarine
5/29/2013 52cm@cti.ac.at
Terminology

If class A inherits the properties and methods of
class B it is said that class B is derived from
class A

The deriving class is called Base Class.

The derived class is called Child Class.

A class which is not derived from any other class
is called root class.
(c) CTI, Christian V. Madritsch 27
5/29/2013 53cm@cti.ac.at
What becomes inherited?

Child Class inherit:

public and protected Data

public and protected Methods

Child Class does not inherit:

private Data and Methods are present but not visible

constructor(s)

destructor

assignment operator

How to differentiate a Child from the Base Class:

Add new Data or Methods.

Change the behavior of existing Methods (overwrite)
5/29/2013 54cm@cti.ac.at
Inheritance (i)

Class Person:

Abstract Description

Data: Vorname, Nachname, Adresse,
Telefonnummer

Methods: sitzen, stehen, gehen, laufen

Class Student:

Consists of the same Data and Methods as
Person, but extends it by new Data and
Methods:

Data: Matrikelnummer, Fächer, Noten

Methods: Prüfung machen, Vorlesung besuchen,
Hausübung machen
(c) CTI, Christian V. Madritsch 28
5/29/2013 55cm@cti.ac.at
Inheritance (ii)

Class Student inherits Data and Methods from class Person.

A student is a person

One instanze of Student consists of the following Data and
Methods:

Data:

Vorname, Nachname, Adresse, Telefonnummer,
Matrikelnummer, Fächer, Noten

Methods:

sitzen, stehen, gehen, laufen, Prüfung machen, Vorlesung
besuchen, Hausübung machen
5/29/2013 56cm@cti.ac.at
Inheritance (iii)

Why should inheritance be used?

Assumption: Class Person does not exist.

Classes Student, Lehrer, Administrator contain all Data and
Methods of Person

If new Data is added (e.g. Mobile phone number), each class needs
to be changed.

If class Person exists, only Person needs to be changed, since all other
classes inherite its data.
(c) CTI, Christian V. Madritsch 29
5/29/2013 57cm@cti.ac.at
Different kinds of inheritance

Single Inheritance

A child class is derived from one base class.
class A{};
class B : public A{ // B derived from A
...
};

Multiple Inheritance

A child class is derived from multiple base classes.
class A{};
class B{};
class C : public B , public A{// C is derived from B and A
...
};
29.05.2013 58cm@cti.ac.at
Access and Inheritance (i)

Visibility of inherited public-components:

All public components of the base class are public in
the derived class.

Visibility of inherited private-components:

All private components of the base class are not
accessible in the derived class, but they are contained!

Visibility of inherited protected-components :

The protected components of the base class are
accessible in the derived class, but private in derived
from Derived classes.
(c) CTI, Christian V. Madritsch 30
29.05.2013 59cm@cti.ac.at
Access and Inheritance (ii)
Kind of
Inheritance
Visibility in the Baseclass
public
protected
private
public
protected
private
protected
protected
private
no access
no access
no access
public
protected
private
Access in the
Derived class
5/29/2013 60cm@cti.ac.at
Constructor and Destructor

The constructor of the Base class is called first the constructor
of the derived class next.
class A{
A(){} // Constructor of A
};
class B : public A{
B():A(){} // Const. B calls Const. A
};

The destructors are called in the inverse order.
A
App
App a;
A - Part
App - Part
1
st
2
nd
Object creation in
case of Inheritance
Destruction works in
reverse order!
(c) CTI, Christian V. Madritsch 31
5/29/2013 61cm@cti.ac.at
Polymorphism (i)

…through Variation of Parameters

Templates

Function Overloading

… through Variation of Methods

Virtual Functions (Redefinition)

Operator Overloading

Late Binding
Polymor-
phismus
Parameter
Funktionen
Templates
Überladen
von
Funktionen
Operatoren
virtuelle
Funktionen
spätes
Binden
29.05.2013 62cm@cti.ac.at
Polymorphismus (ii)

Class A is the base class of classes B and C.

Pointers of type A can point to objects of type B and C.

If these classes contain Methods with similar names,
calling these Methods leads to different results.

If at compile-time the assignment to the methods
can be done: early binding

Redifinition

Overloading

If at run-time the assignment to the methods
happens: late binding.

Genuine Polymorphism
(c) CTI, Christian V. Madritsch 32
29.05.2013 63cm@cti.ac.at
Redefinition is no Polymorphism
class A {
void f (X p) { ... } // A::f
...
};
class B : public A {
void f (X p) { ... } // REDEFINITION: B::f overwrites A::f
...
};
A *a; B *b; X x;
a = new A;
a->f(x); // calls A::f
b = new B;
b->f(x); // calls B::f, A::f is overloaded
a = new B;
a->f(x); // calls A::f <<--- BECAUSE a is of Type A*!!!!
29.05.2013 64cm@cti.ac.at
Genuine Polymorphism(i)
class A {
virtual void f (X p) { ... } // A::f polymorph
...
};
class B : public A {
void f (X p) { ... } // POLYMORPHISM: A::f is replaced
...
};
A *a; B *b; X x;
a = new A;
a->f(x); // calls A::f
b = new B;
b->f(x); // calls B::f
a = new B;
a->f(x); // calls B::f <<--- ALTHOUGH a is of Type A*
// and because *a NOW of Type B is
(c) CTI, Christian V. Madritsch 33
29.05.2013 65cm@cti.ac.at
Genuine Polymorphism(ii)
#include <iostream>
using namespace std;
class A{
public:
void show(){cout << "A" << endl;}
};
class B : public A{
void show(){cout << "B" << endl;}
};
class C : public A{
void show(){cout << "C" << endl;}
};
class D : public A{
void show(){cout << "D" << endl;}
};
int main(void){
A* arr[4];
arr[0] = new A;arr[1] = new B; arr[2] = new C; arr[3] = new D;
for(int i = 0; i < 4; i++)
arr[i]->show();
return 0;
}
29.05.2013 66cm@cti.ac.at
Genuine Polymorphism(iii)
#include <iostream>
using namespace std;
class A{
public:
virtual void show(){cout << "A" << endl;}
};
class B : public A{
void show(){cout << "B" << endl;}
};
class C : public A{
void show(){cout << "C" << endl;}
};
class D : public A{
void show(){cout << "D" << endl;}
};
int main(void){
A* arr[4];
arr[0] = new A;arr[1] = new B; arr[2] = new C; arr[3] = new D;
for(int i = 0; i < 4; i++)
arr[i]->show();
return 0;
}
(c) CTI, Christian V. Madritsch 34
29.05.2013 67cm@cti.ac.at
Genuine Polymorphism(iv)

Constructor and Destructor

Constructors are never virtual

Destructors could be virtual

Pure virtual Methods (Abstract Base Class)

With „=0“ instead of a method definition

Virtual without pointers or references is useless!
29.05.2013 68cm@cti.ac.at
Run-Time Type Information (RTTI)

In C++ polymorph Objects can use Run-Time Type Information
features.

Using RTTI, the type of a polymorphic object can be determined at run-time.
dynamic_cast <type id> (expression)
Used for conversion of polymorphic types
reinterpret_cast <type id> (expression)
Used for simple reinterpretation of bits
static_cast <type id> (expression)
Used for conversion of nonpolymorphic types.
const_cast <type id> (expression)
Used to remove the const, volatile, and __unaligned attributes.
typeid
(c) CTI, Christian V. Madritsch 35
29.05.2013 69cm@cti.ac.at
dynamic_cast
class Basis {
public:
virtual void f() {};// <<<---- virtual Method
int b; // each Object needs a Type Marker
}; // to call the right Variation of f
class Ab : public Basis {
public:
int a;
};
...
Basis * pb = new Ab; // pb points formally to a base object
pb->a = 0; // ERROR: pb->a is not accessible
Ab * pa;
pa = pb; // ERROR: Assignment not allowed!
pa = dynamic_cast<Ab *>(pb); // pa points formally to an Ab-Object
pa->a = 0; // OK
29.05.2013 70cm@cti.ac.at
typeid
#include <iostream> #include <typeinfo> using namespace std;
class Base {
public:
Base () {}
virtual void f () {} // <<---- virtual Method
};
class Derived : public Base {
public:
Derived () {}
};
int main() {
Base * pb1 = new Base;
Base * pb2 = new Derived;
Derived * pa = new Derived;
// print Typenames
cout << typeid(*pb1).name() << endl; // Output: Base
cout << typeid(*pb2).name() << endl; // Output: Derived
cout << typeid(*pa).name() << endl; // Output: Derived
Derived ab;
Base * pb;
pb = ....
// Type dynamic test
if ( typeid(*pb) == typeid(ab) ) {
... pb points to a derived object ...
}
}
(c) CTI, Christian V. Madritsch 36
29.05.2013 71cm@cti.ac.at
Function Overloading (i)

Functions with the same name can be overloaded by different types of
functions.
#include <iostream>
using namespace std;
double meanvalue(double a[],int size) {
double sum = 0;
for (int i=0; i<size; i++) sum += a[i];
return sum/size;
}
double meanvalue(int a[],int size) {
int sum = 0;
for (int i=0; i<size; i++) sum += a[i];
return (double)sum/size;
}
int main(void) {
int i[] = {1, 2, 3, 4, 5};
double d[] = {1.1, 2.2, 3.3, 4.4, 5.5};
cout << meanvalue(i,5) << " int\n";
cout << meanvalue(d,5) << " double\n";
return 0;
}
29.05.2013 72cm@cti.ac.at
Function Overloading (ii)
#include <iostream>
using namespace std;
class A{
public:
void show(char ch){cout << "A::zeige " << ch << endl;}
};
class B : public A{
public:
void show(char ch){cout << "B::zeige " << ch << endl;} // overloaded
void show(int i){cout << "B::zeige " << i << endl;} // overloaded
};
class C : public B{
public:
void show(char ch){cout << "C::zeige " << ch << endl;} // overloaded
void show(double x){cout << "C::zeige " << x << endl;} // overloaded
};
int main(void){
A a; B b; C c;
a.show('A');
b.show('B');
b.show(12);
c.show('C');
c.show(3.1415);
return 0;
}
(c) CTI, Christian V. Madritsch 37
29.05.2013 73cm@cti.ac.at
Operator overloading (i)

Operators can be overloaded with new actions.
class Vector {
private:
float x,y;
public:
Vector operator+ (Vector b) { // add b to me!
Vector res;
res.x = x + b.x;
res.y = y + b.y;
return res;
}
};
Vector a, b;
a + b; // a.operator+ (b);

A binary operator (e.g. +) is overloaded as method with one argument.
29.05.2013 74cm@cti.ac.at
Operator overloading (ii)

Unary Operators are defined as methods without an argument.
class Vector {
public:
Vector operator- () { // unary minus
Vector res;
res.x = -x;
res.y = -y;
return res;
}
private:
float x, y;
};
Vector a, b;
b = -a;

The following operators cannnot be overloaded:

. * :: ?: sizeof
(c) CTI, Christian V. Madritsch 38
29.05.2013 75cm@cti.ac.at
Operator overloading (iii)
class Frac{
Frac operator+(Frac &b){
return Frac(den*b.num+num*b.den,num*b.num);}
Frac operator-(Frac &b){
return Frac(den*b.num-num*b.den,num*b.num);}
Frac operator*(Frac &b){
return Frac(den*b.den,num*b.num);}
Frac operator/(Frac &b){
return Frac(den*b.num,num*b.den);}
};
a + b is interpreted as a.operator+(b)
29.05.2013 76cm@cti.ac.at
Ausnahmebehandlung (i)

Ein üblicher Weg bei der Fehlerbehandlung ist die Rückgabe
eines Wertes, der nicht als Funktionswert auftreten kann und
somit einen Fehler anzeigt.

Quadratwurzel: -1

Für den Fall, dass auftretende Fehler vom aufrufenden
Programmteil behandelt werden können, stellt C++ folgenden
Ausnahmemechanismus auf:

Ein Funktionsaufruf wird versucht: try

Wird ein Fehler entdeck, den die Funktion nicht beheben
kann, wird eine Ausnahme geworfen: throw

Die Ausnahme wird von einem anderen Programmteil zur
Fehlerbehandlung aufgefangen: catch
(c) CTI, Christian V. Madritsch 39
29.05.2013 77cm@cti.ac.at
Ausnahmebehandlung (ii)
#include <iostream>
using namespace std;
int main(void){
int b=5, c=0;
double a;
try{
if(c == 0)
throw"Nenner Null";
a=b/c;
}
catch(char *str){
cout << "Ausnahmefall: " << str << endl;
}
return 0;
}
29.05.2013 78cm@cti.ac.at
Speicherklassen (i)

Jede Variable besitzt das Attribut Speicherklasse:

auto: Speicher für diese Variable wird automatisch beim Eintritt
in den Programmblock reserviert

extern: Speicher für diese Variable wird in einem anderen
(getrennt übersetzten) Programmteil reserviert

register: Wenn möglich, soll diese Variable in einem Register
des Prozessors gehalten werden. Ist dies nicht möglich, wird
die Variable wie mit Speicherklasse auto behandelt.

static: Die Variable behält den Wert nach Austritt aus dem
Block, in dem sie definiert worden ist. Zudem sind static
Variable nur in dem Programmteil ''sichtbar'', in dem sie
definiert worden sind

const: Der Variableninhalt kann nur einmal gesetzt und später
nicht mehr verändert werden.

volatile: Der Variableninhalt kann ohne explizite
Programmanweisung verändert werden (bspw. Memory-
mapped Hardware-Register oder Signalbehandlung); durch
diese Deklaration werden gewisse Optimierungen bei der
Kompilation deaktiviert.
(c) CTI, Christian V. Madritsch 40
29.05.2013 79cm@cti.ac.at
Speicherklassen (ii)

Speicherklasse auto
int f(int i) {
auto int a = 2; // wird bei Funktions-
// eintritt initialisiert
int b; // standardmäßig wird
. ..// auto angenommen
}

Speicherklasse extern
#include <iostream>
using namespace std;
double kreis_flaeche(double radius) {
return 3.141592 * radius * radius;
}
extern double kreis_flaeche(double);
int main(void) {
double x = 8;
cout << "Flaeche von Kreis mit Radius " << x << " = " << kreis_flaeche(x);
return 0;
}
29.05.2013 80cm@cti.ac.at
Speicherklassen (iii)

Speicherklasse static
#include <iostream>
using namespace std;
void f() {
static int zaehler1 = 0; // bei Programmstart initialisiert
int zaehler2 = 0; // bei Funktionsaufruf initialisiert
cout << "Zaehler 1 = " << zaehler1++
<< ", Zaehler 2 = " << zaehler2++ << endl;
}
int main(void) {
f();
f();
f();
return 0;
}
(c) CTI, Christian V. Madritsch 41
29.05.2013 81cm@cti.ac.at
Speicherklassen (iv)

Speicherklasse const
#include <iostream>
using namespace std;
const long double PI = 3.1415926535897932385;
const char string1[20] = "Konstante 1";
const char *string2 = "Konstante 2";
int main(void) {
PI = 3.13; // ungültig
string1[0] = 'x'; // ungültig
string2++;
*string2 = 'y'; // ungültig
return 0;
}
29.05.2013 82cm@cti.ac.at
Speicherklassen (v)

Speicherklasse const
#include <iostream>
using namespace std;
int i = 1;// Ganzzahl
int const k = 4711;// konstante Ganzzahl
int *const k_zeiger = &i;// konstanter Zeiger
int const *zeiger_auf_k1 = &k;// Zeiger auf eine konst. Ganzzahl
const int *zeiger_auf_k2 = &k; // Zeiger auf eine konst. Ganzzahl
int const *const k_zeiger_auf_k = &i; // konst. Zeiger auf
// konst. Ganzzahl
int main(void) {
*k_zeiger = 2; // ok
k_zeiger++; // ungültig
const kk = 100;
*zeiger_auf_k1 = 2; // ungültig
zeiger_auf_k1 = &kk; // ok
*k_zeiger_auf_k = 2; // ungültig
k_zeiger_auf_k = &kk; // ungültig
return 0;
}