an introduction to c++ lecture 08: abstractionekp · abstraction this procedure is called...

Post on 21-Jun-2020

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

INSTITUTE OF EXPERIMENTAL PARTICLE PHYSICS (IEKP) – PHYSICS FACULTY

An Introduction to C++

Lecture 08: Abstraction

Roger Wolf18. Mai 2018

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

INSTITUTE OF EXPERIMENTAL PARTICLE PHYSICS (IEKP) – PHYSICS FACULTY

Part 1:

Abstraction

1/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

The case of abstraction

● Imagine you have a program to manage bank accounts. This program has two classes Savings and Checking, which differ in the way withdrawals are charged.

● The two classes have the following structure:

Checking

withdrawal()

deposit()

accountNo()

accountNo_balance_

Savings

withdrawal()

deposit()

accountNo()

accountNo_balance_noWithdrawals_

The first 10 withdrawals are for free (requires one additional member)

Withdrawals are higher charged if the balance falls below 100$

2/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Savings

withdrawal()

deposit()

accountNo()

accountNo_balance_noWithdrawals_

The case of abstraction

● The two classes have the following structure:

● How can the redundancy in the defini-tion of these two classes be removed?

The first 10 withdrawals are for free (requires one additional member)

Checking

withdrawal()

deposit()

accountNo()

accountNo_balance_

● Imagine you have a program to manage bank accounts. This program has two classes Savings and Checking, which differ in the way withdrawals are charged.

2/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Solution-1

● Let Savings inherit from Checking, add the additional member, and overload withdrawal().

● The two classes have the following structure:

Savings

withdrawal() noWithdrawals_IS_A

inherits from

Checking

withdrawal()

deposit()

accountNo()

accountNo_balance_

3/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Solution-1

● The two classes have the following structure:

Why Solution-1 is suboptimal:

● A savings account is not a checking account. The class structure does not reflect reality.

● This can lead to misunderstandings and errors.

● Savings depends on Checking. What if Checking changes one day?

Savings

withdrawal() noWithdrawals_

Checking

withdrawal()

deposit()

accountNo()

accountNo_balance_

● Let Savings inherit from Checking, add the additional member, and overload withdrawal().

3/32

IS_A

inherits from

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Solution-2

● Savings and Checking both describe accounts: introduce Account as a common base class.

Account

withdrawal()

deposit()

accountNo()

accountNo_balance_

Savings

withdrawal() noWithdrawals_

inherits from

Checking

withdrawal()

IS_AIS_Ainherits from

● Both derived classes overload withdrawal() corresponding to their attributes.

4/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Abstraction

● This procedure is called abstraction.

● It follows our natural intuition: try to identify what certain groups of objects have in common. Subsume it into a common base class.

● Such abstraction hierarchies have no unique solution. Depending on the use case and level of required knowledge this can lead different answers.

● Identifying the proper abstraction model for your problem might well happen in an iterative procedure as described in Lecture­05.

4/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Problem with Solution-2

● What should be the implementation of Account::withdrawal()?

● Account is an abstraction of Checking and Savings. It cannot be made concrete (see slide 7).

5/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Problem with Solution-2

● What should be the implementation of Account::withdrawal()?

● Another example from nature: tigers, apes and giraffes are mammals → but you wont find an animal on earth that is just a mammal.

5/32

● Account is an abstraction of Checking and Savings. It cannot be made concrete (see slide 7).

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

The abstract base class

● The C++ solution to this problem is to provide explicitly NO implementation for withdrawal() in the base class.

● Account is then called abstract

6/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

The abstract base class

This indicates that withdrawal() will not have an implementation in Account

● The C++ solution to this problem is to provide explicitly NO implementation for withdrawal() in the base class.

● Account is then called abstract

6/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

The abstract base class

This indicates that withdrawal() will not have an implementation in Account

A possible implementation in Savings

● The C++ solution to this problem is to provide explicitly NO implementation for withdrawal() in the base class.

● Account is then called abstract

6/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

● The C++ solution to this problem is to provide explicitly NO implementation for withdrawal() in the base class.

● Account is then called abstract

The abstract base class

This indicates that withdrawal() will not have an implementation in Account

A possible implementation in Savings

A possible implementation in Checking

6/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Object declaration

● No objects can be instantiated from Account (after all its implementation is incomplete):

● To make a concrete class, all member functions (e.g. of Account) have to be implemented (=overloaded) in derived classes. Implementing only a fraction can be done to create another abstract base class.

7/32 Back to slide 5

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Abstract classes as arguments

● No problem, as long as the passed arguments are concrete classes. This is automatically the case if you pass objects.

8/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Abstract classes as arguments

● No problem, as long as the passed arguments are concrete classes. This is automatically the case if you pass objects.

No problem as long as a concrete derived class is passed

8/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Why declare Account::withdrawal() at all?

● If withdrawal() has a real implementation only in Savings and Checking, why do I need to have a declaration of this function in Account at all?

Imagine withdrawal() were not declared:

● What function should be called? Account has no function withdrawal().

● How should C++ know how to overload it in the context of polymorphism?

9/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

What are abstract classes good for?

● They allow you to reduce redundancies.

● They minimize your work in debugging and code maintenance.

● They allow to write code that is closer to reality/daily life experience.

● They allow to use polymorphism:E.g. we could have implemented withdrawal() in each derived class w/o polymorphism:

10/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

What are abstract classes good for?

● They allow you to reduce redundancies.

● They minimize your work in debugging and code maintenance.

● They allow to write code that is closer to reality/daily life experience.

● They allow to use polymorphism:E.g. we could have implemented withdrawal() in each derived class w/o polymorphism:

replace by...

10/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

What are abstract classes good for?

● They allow you to reduce redundancies.

● They minimize your work in debugging and code maintenance.

● They allow to write code that is closer to reality/daily life experience.

● They allow to use polymorphism:E.g. we could have implemented withdrawal() in each derived class w/o polymorphism:

replace by...

Note: not only that overloading of fn() is required. The use of fn() also requires more knowledge of Savings and Checking. Together with less intuitive use → doubly error prone!

10/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

A new type of interface

● You can also use abstract classes to define interfaces for code developers. Imagine the following scenario:

ObjectCreator

virtual readFrom()=0

virtual writeTo()=0

virtual create()=0

used in… Application● Provides a container with basic objects.● ObjectCreator has read/write access to

this container to write more complex objects composed of the basic objects into it.

ToyCreatorPatternCreator

PairCreatorXXCreator

Der

ived

con

cret

e cl

asse

sIn

terf

ace

to A

pplic

atio

n fo

r th

e de

velo

per

11/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Run time type identification (RTTI)

● Sometimes you might want to know the runtime type of an object in a function. This can be obtained from dynamic downcasts.

12/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Run time type identification (RTTI)

● Sometimes you might want to know the runtime type of an object in a function. This can be obtained from dynamic downcasts.

● You can apply dynamic downcasts, which are evaluated at runtime on pointers or references.

● For references they throw exceptions, e.g. if acc does not have the runtime type Savings.

● For pointers it returns a NULL pointer.

12/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Run time type identification (RTTI)

● This functionality is controversial: it foils the idea of object oriented programming, e.g. fn(Account* ) pretends that you only need to know something about Account, but inside more knowledge about Savings is also required.

● If used extensively it points to procedural programming in an object oriented language/disguise.

● If you encounter this use case try to think of a better maintainable solution.

13/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

How to prevent RTTI

● Add an abstract member function noWithdrawals() to Account.

● Overload it in Savings with a corresponding function that returns the value.

● Overload it in Checking with an empty function.

14/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

INSTITUTE OF EXPERIMENTAL PARTICLE PHYSICS (IEKP) – PHYSICS FACULTY

Part 2:

Multiple inheritance

15/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Multiple inheritance

● Sometimes your class inherits attributes from more than one abstract instance. Imagine an AmphibianVehicle, which inherits from Boat and Car.

Boat

motor

propeller

hull

Car

motor

wheels

indicators

AmphibianVehicle

motor

propeller

hull

motor

wheels

indicators

16/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Multiple inheritance

● Sometimes your class inherits attributes from more than one abstract instance. Imagine an AmphibianVehicle, which inherits from Boat and Car.

Inheritance from two base classes

17/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Ambiguities due to inheritance

● As shown in the following example multiple inheritance can lead to ambiguities:

What class do we refer to here?

18/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Ambiguities due to inheritance

● As shown in the following example multiple inheritance can lead to ambiguities:

What class do we refer to here?

This can formally be resolved by identifying the class by namespace

18/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Another case of abstraction

● This solution is still unsatisfactory, as long our AmphibianVehicle has only one motor. In this case our problem originates from an improper abstraction. What we want looks more like this:

Boat

motor

propeller

...

EDVehicle

motor

Car

motor

wheels

...

AmphibianVehicle

motor

...

19/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Another case of abstraction

● This solution is still unsatisfactory, as long our AmphibianVehicle has only one motor. In this case our problem originates from an improper abstraction. What we want looks more like this:

Boat

motor

propeller

...

EDVehicle

motor

Car

motor

wheels

...

AmphibianVehicle

motor

...

20/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Another case of abstraction

● This solution is still unsatisfactory, as long our AmphibianVehicle has only one motor. In this case our problem originates from an improper abstraction. What we want looks more like this:

Boat

motor

propeller

...

EDVehicle

motor

Car

motor

wheels

...

AmphibianVehicle

motor

...

21/32

Executable for testing...

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Another case of abstraction

● This solution is still unsatisfactory, as long our AmphibianVehicle has only one motor. In this case our problem originates from an improper abstraction. What we want looks more like this:

Boat

motor

propeller

...

EDVehicle

motor

Car

motor

wheels

...

AmphibianVehicle

motor

...

21/32

Executable for testing...

● If you try to compile this it wont work either: even if you explicitly cast AmphibianVehicle to EDVehicle the compiler will complain that it cannot resolve which motor you are talking about.

● The reason lies in the way the memory block is filled (see slide 22)

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

What hast thou done?

EDVehicle

Boat

EDVehicle

Car

Am

phib

ianV

ehic

le

● The result of our implementation:

How an AmphibianVehicle looks like in the memory block

22/32 Back to slide 21

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

What hast thou done?

EDVehicle

Boat

EDVehicle

Car

Am

phib

ianV

ehic

le

Boat

motor

propeller

...

EDVehicle

motor

Car

motor

wheels

...

AmphibianVehicle

motor

...

EDVehicle

motor

● The result of our implementation:

How an AmphibianVehicle looks like in the memory block

22/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Virtual inheritance

● We can still achieve what we want by virtual inheritance:

23/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Virtual inheritance

● We can still achieve what we want by virtual inheritance:

Results in the intended inheritance structure…

23/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Virtual inheritance

● We can still achieve what we want by virtual inheritance:

Results in the intended inheritance structure…

23/32

Everything fine here

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Virtual inheritance

● We can still achieve what we want by virtual inheritance:

Results in the intended inheritance structure…

23/32

Everything fine here

EDVehicle

Boat

Car

Am

phib

ianV

ehic

le

How an AmphibianVehicle looks like in the memory block

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

INSTITUTE OF EXPERIMENTAL PARTICLE PHYSICS (IEKP) – PHYSICS FACULTY

Part 3:

Templating

24/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-1: function overloading

25/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-1: function overloading

● This solution is not very satisfactory since you have to implement the function over and over again.

25/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-2: template functions

● The same can be achieved via a template function.

26/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-2: template functions

● The same can be achieved via a template function.

Keyword

26/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-2: template functions

● The same can be achieved via a template function.

Keyword Class type

26/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-2: template functions

● The same can be achieved via a template function.

Keyword Class type

T is used as a variable throughout the function declaration part

26/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-2: template functions

● The same can be achieved via a template function.

Keyword Class type

T is used as a variable throughout the function declaration part

● A more complex example:

27/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template functions

● Take a function max(a,b) that is supposed to return the larger of two values. Imagine you would like to use it equally well for int, float, double, …

Solution-2: template functions

● The same can be achieved via a template function.

Keyword Class type

T is used as a variable throughout the function declaration part

● A more complex example:

● <…> can have more argu-ments.

● All arguments in <…> must be used in the following declaration.

27/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

General remarks

● A function template does not become a C++ function before your fully specify it (=fully expand its template arguments).

● For full expansion a reference to the function is sufficient.

● Consequently you can write as many template functions as you want into your source code. They will not use any memory in your executable until expanded. Each fully specialized version will use its own memory in the executable though, i.e. int max(int, int) takes its own space as well as float max(float, float), aso …

● Consequently you can even write code with syntax errors. Since C++ will compile it only when fully expanded somewhere in your code, your code would compile without complaints unless you do expand somewhere.

28/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Potential ambiguities

● There may be danger of confusion. See the following example:

29/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

● There may be danger of confusion. See the following example:

What function will be called here?

29/32

Potential ambiguities

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

● There may be danger of confusion. See the following example:

What function will be called here?

To resolve this kind of confusion the following ordering applies:● Search for an explicit function that fits to

the arguments.● Search for a function template that can fit

the arguments when expanded properly.● Search for an explicit function that can fit

if one or more arguments are converted.

29/32

Potential ambiguities

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template classes

● The concept of template functions can be extended to classes. Check the following example to see how this works:

30/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template classes

● The concept of template functions can be extended to classes. Check the following example to see how this works:

Keyword and template arguments

30/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template classes

● The concept of template functions can be extended to classes. Check the following example to see how this works:

Keyword and template arguments

Declaration of a pointer of type T

30/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template classes

● The concept of template functions can be extended to classes. Check the following example to see how this works:

Keyword and template arguments

Declaration of a pointer of type T

30/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template classes

● The concept of template functions can be extended to classes. Check the following example to see how this works:

Keyword and template arguments

Declaration of a pointer of type T

Function definition outside the class declaration

30/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Template classes

● The concept of template functions can be extended to classes. Check the following example to see how this works:

30/32

Example of usage

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Final remarks

● The most obvious use case for templates in C++ programming are container classes, as introduced in Lecture­03, e.g. std::vector<T>.

31/32

Priv. Doz. Dr. Roger Wolf http://ekpwww.physik.uni­karlsruhe.de/~rwolf/

Summary

● Abstraction.

● The abstract base class.

● Run time type identification (RTTI).

● Multiple inheritance.

● Virtual inheritance.

● Template functions.

● Template classes.

32/32

top related