Anda di halaman 1dari 47

Advanced Programming Techniques

Constructors and Destructors


Signal_A dapter init$% raise_tick() raise_select_prev() raise_select_next() raise_triptime_alarm() raise_ignition_on() raise_ignition_off() raise_reset_program() raise_reset_all_programs() raise_eeprom_changed() raise_memlevel_down() raise_memlevel_up() State_Control on_ select_pre&$% on_select_next() on_tick() on_triptime_alarm() on_mem_level_down() on_mem_level_up() on_ignition_on() on_ignition_off() on_reset_program() on_reset_all_programs() on_eeprom_changed() 33ctor44 init$% #tate_Control_A UDI on_select_ne t$% on_tick$% on_triptime_alarm$% on_ select_pre&$% on_mem_le&el_down$% on_mem_le&el_up$% on_ignition_off$% on_ignition_on$% reset_program$% reset_all_programs$% Create$% C o n t r o l # e c t i o n 5

Data_A dapter

Program calc_value() : void displa () : void ignition_on() : void ignition_off$% 6 &oid reset() : void !!"## eeprom_changed() : $$$ need_recalc() : %ool

I mpl_Tripdistance

I mpl_Tripdistance_A UDI

Im p_ Tr i pt i m e_ Al ar m

I mpl_Triptime_Alarm_A UDI

I mpl_Triptime

C a l c u l a t i o n

I mpl_Mean_Consumption

Prof. Dr.-Ing. Peter Fromm Prof. Dr.-Ing. Michael Lipp

I mpl_Current_Consumption

I mpl_Mean_Consumption_A UDI # e c t I mpl_Current_Consumption_AUDIi o n

Im pl _ A&er age_ #peed Im pl _ 2ange Displa _A dapter clear() write_str$% !!draft## write_s m%ol() 33ctor44 init$% Display_Triptime_Alarm_A UDI

Display_Triptime_A larm ) #+,-./C $from #*#% Displa _& alue show(value : dword) : void Display_Mean_Consumption

D i s p l a y

Display_Mean_Consumtion_A UDI # e c t i Display_Current_Consumption_AUDI o n

)#+,-win01 $from #*#%

Display_Current_Consumption

console-win01 $from #*#%

Display_Tripdistance

Display_Tripdistance_A UDI

(classes ( of lefthand coloumn act as inerface to hareware and )#. They are declared abstract in the main class hierarchy and implemented in se&eral #*# packages.

coloumns in the middel build up the trip computer core. All code has to be independent of manufacturer. The Impl_''' and Display_''' classes describe what fla&ours of program functionality are e pected

The classes on the right side all belong to the AUDI package and are not part of the main class hierarchy. They are included to show where the main class hierarchy has to be e panded for manufactorer!s re"uirements

Content

Learn a%out class initiali&ation 'nderstand the this-Pointer 'nderstand the tas( of the )onstructor and Destructor 'nderstand Default Parameters 'nderstand the )op* )onstructor

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Wrap-Up Learned the difference %et+een classes and o%,ects -e did some scoping using private, protected and pu%lic Implemented some methods and attri%utes Learned more a%out requirements Functional requirements .on-Functional requirements

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Wrap-Up UML Use Case Diagram

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Wrapup Objects and C asses The )11 programming language allo+s programmers to define program-specific data t*pes through the use of structures and c asses. Instances of these datat*pes are (no+n as objects and can contain mem%er variab es, constants, mem%er !unctions, and overloaded operators defined %* the programmer. 2*ntacticall*, structures and classes are e3tensions of the ) struct datat*pe, +hich cannot contain functions or overloaded operators.

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Objects and C asses Differences %et+een ) structs and )11 classes ) structs onl* contain glo%all* visi%le data t*pes )11 classes include data t*pes 5attri%utes6 and in addition mem%er functions 5methods6 and overloaded operators )11 classes have different section to control the visi%ilit* of the attri%utes and methods )11 classes support inheritance and pol*morphism 5+ill %e sho+n later6

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

C"" c ass advantages Direct access to data controlla%le via scope private onl* methods of the class protected onl* methods from the class or from derived classes pu%lic all classes 8etter coding st*le9 provide getter and setter functions access is controlled illegal parameters and operations can %e avoided e3ceptions can %e handled Initiali&ation via )onstructors Initiali&ation supports different parameter sets )op*-)onstructor supports controlled cop*ing of contents of other o%,ects

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#nitia i$ation o! variab es ;ne ma,or pro%lem of programming are varia%les containing the +rong data Ariane roc(et Mars e3plorer < )auses Forgotten initiali&ation 5read %efore +rite6 Implementation %ugs 5meter versus feet6 )orrupted pointers Arra*s out of %ounces 'n%alanced operations <and some pitfalls of the )-language

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#nitia i$ation o! %ariab es


#include <iostream> #include <stdlib.h> using namespace std; #include "CInit.h" int global_a = 12; int global_b = global_a; int main ( oid! " int c = 12#; cout << "global_a = " << global_a << "$ global_b = " << global_b << "$ c = " << c << endl; s%stem("pause"!; return &'I(_)*CC&)); +

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#nitia i$ation o! structs


struct sCoordinate" int , = -; int % = -; + class CCoordinate " public. int m_, = -; int m_% = -; + error C2/01. 2sCoordinate..,2 . onl% static const integral data members can be initiali3ed 4ithin a class error C2/01. 2CCoordinate..m_,2 . onl% static const integral data members can be initiali3ed 4ithin a class

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#$

Memor& a ocation in C"" To initiali&e varia%les, memor* must %e allocated. The relevant question seems9 -hen is it allocated >lo%al varia%les upon declaration Local varia%les upon declaration 2tructs upon declaration of a varia%le using the struct )lasses upon declaration of o%,ects of the class

)lasses descri%e the o%,ect structure, the* do not allocate memor*.


At least not for ?normal@ mem%er varia%les static mem%ers +ill %e handled later.

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

##

T&pes and %ariab es ' Objects )lasses are compara%le to varia%le t*pes ;%,ects are compara%le to varia%les int m*IntegerAaria%le B $C Aaria%le Identifier Initial Aalue

T*pe

))oordinate m*)oordinate5$,/6 ;%,ect Identifier Parameters for )onstructor

)lass

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

()p icit and imp icit initia i$ation -hatDs the difference %et+een9 int aC int % B $C int c B # !C void main56 E int aaC int %% B $C int cc B # !C int dC d B # !C F

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#!

Object #nitia i$ation -h* is this not possi%le9 ))oordinate m*)oordinate# B 5$,/6

8ut ho+ a%out this9 string m*2tring B ?Gello +orld@

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#/

Object #nitia i$ation The initiali&ation of o%,ect is more comple3 than simple varia%les 2everal varia%les inside the o%,ect need to %e initiali&ed Aalues are chec(ed for valid range D*namic memor* is assigned <

Initiali&ation of o%,ects is performed %* a specific function, the )onstructor

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#0

Constructors )onstructors %ehave ?almost@ similar to normal operations The are called automaticall* +henever an o%,ect is generated %* declaration %* allocation using ne+ The* ma* %e called manuall* to generate a temporar* o%,ect 5e.g. parameter, return value6 Mandator*H )onventions .ame of the )lass .o return value Parameters and default parameters supported .um%er of constructors #..n

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#4

This-Pointer
The ?this@ Pointer points to the mem%er varia%les of the o%,ect currentl* ?in use@ It is automaticall* added to ever* method call %* the compiler It is equal to the address of the first mem%er varia%le of the o%,ect It ensures that the operations are performed on the right data

o# )lass int mI3C int mI*C set5int 3, int *6 mI3 B # ! mI* B /04 o mI3 B # ! mI* B /04 $3#$$: $3#$$) o .this o .set5!,/6 $3#$$$ $3#$$/ o#.this o#.set5#, 6

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#7

()amp e o! a simp e constructor


class CCoordinate " public. int m_,; int m_%; public. CCoordinate(! " cout << "5ust generated a CCoordinate ob6ect at " << this << endl; m_, = -; m_% = -; + +;

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#:

Constructor *ith Parameters and +ange Chec,


class CCoordinate2 " public. int m_,; int m_%; public. CCoordinate2(int ,$ int %! " i7 (,>- 88 %>-! " m_, = ,; m_% = %; + else " m_, = -; m_% = -; + cout << "5ust generated a CCoordinate ob6ect at " << this << " 4ith the alues (" << m_, << "$ " << m_% << "!" << endl; + +;

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

#=

Constructor *ith de!au t parameters


class CCoordinate# " public. int m_,; int m_%; string m_name; public. CCoordinate#(int , = -$ int % = -$ string name = "9o9ame"! " m_name = name; i7 (,>- 88 %>-! " m_, = ,; Default-Parameters are m_% = %; + a ne+ feature of )11 else " m_, = -; m_% = -; + cout << ":enerated a CCoordinate ob6ect called " << m_name << " at " << this << " 4ith the alues (" << m_, << "$ " << m_% << "!" << endl; + +;
Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp !"#$"# $

Di!!erent *a&s o! imp ementing a constructor


;;<eclaration in the class.h 7ile class m%class" pri ate. int ,$ %; public. m%class(! ", = -; % = -;+ m%class(int a$ int b! . ,(a!$ %(b! "+; m%class(int a!; ;; Implementation C 7ile + ;;<e7inition m%class..m%class(int a! " , = a; % = a; +

More a%out this in the lecture a%out inheritance

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Design Conventions !or Constructors Al+a*s provide a constructor Provide parameters including default values for improved fle3i%ilit* 'se the constructor for range chec(s 'se the this-Pointer for eas* trace information

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Destructors Destructors %ehave ?almost@ similar li(e normal operations The are called automaticall* +henever an o%,ect is destro*ed local o%,ect after leaving the function glo%al o%,ect after leaving the program deletion of allocated memor* The* should not %e called manuall* ;nl* needed +hen cleanup operations are required 5delete d*namic memor*, releasing of ressources6 )onventions .ame of the )lass .o return value, no parameters .um%er of constructors $..#

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

()amp e o! a Destructor
class CCoordinate1 " public. int m_,; int m_%; string m_name; public. CCoordinate1(int , = -$ int % = -$ string name = "9o9ame"!; =CCoordinate(! " cout << "<estro%ing CCoordinate1 ob6ect at " << this << endl; + +;

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Cop& Constructor Definition9 A cop* constructor is a special constructor in the )11 programming language used to create a ne+ o%,ect as a cop* of an e3isting o%,ect. This constructor ta(es a single argument9 a reference to the o%,ect to %e copied. .ormall* the compiler automaticall* creates a cop* constructor for each class 5(no+n as an implicit cop* constructor6 , +hich performs a %it+ise cop* of the data. For special cases this is not sufficient and the programmer creates the cop* constructor, (no+n as an e3plicit cop* constructor. In such cases, the compiler doesnJt create one. A cop* constructor is generall* needed +hen an o%,ect o+ns pointers or non-sharea%le references such as to a file, %ecause the default cop* constructor onl* copies the pointer to the data structure %oth instances +ould +or( on the same memor* conflict

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Cop& Constructor The cop* constructor is defined %* passing a reference to the class as parameter. Additional parameter ma* %e added, %ut a default value must %e provided K3amples9 L5L constM6C recommended, %ecause the reference ma* not %e modified

L5LM6C L5L const volatileM6C L5L volatileM6C L5L constM, int B #$6C L5L constM, dou%le B #.$, int B /$6C

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

Cop& Constructor
class CCoordinate> " public. int m_,; int m_%; string m_name; public. CCoordinate>(int , = -$ int % = -$ string name = "9o9ame"!; CCoordinate>(CCoordinate>8 origin! " cout << "Cop% constructor$ cop%ing 7rom ob6ect " << 8origin << " to " << this << endl; m_, = origin.m_,; m_% = origin.m_%; m_name = "?h$ not him again " @ origin.m_name; ;;5ust to see the di77erence cout << " Called " << m_name << " 4ith the alues (" << m_, << "$ " << m_% << "!" << endl; + =CCoordinate>(!; +;

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

When is the Cop& constructor ca ed;;Cop% Constructor CCoordinate> m%Coordinate>1(1$2$"5oe"!; CCoordinate> m%Coordinate>2 = m%Coordinate>1; ;;Cop% constructor called CCoordinate> m%Coordinate>#(m%Coordinate>1!; ;;Cop% constructor called sampleAunction(m%Coordinate>#!; m%Coordinate># = m%Coordinate>1; ;;Cop% constructor called ;;9ot called

)alled upon cop*-initiali&ation )alled for parameter passing for functions .ot called for assignments overloaded B operator

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

More about memor& management Memor* on a )P' is divided into 5at least6 segments, heap and stac(

2tac( 'sed in e3amples up to no+ Implemented as FIL; 5First In Last ;ut6 %uffer 'sed for function"%loc( local varia%les Geap Nno+n from ?)@ 5malloc"7ree6 'sed %* glo%al data having fi3ed addresses 'sed for d*namic memor* o%,ects 5generated e.g. %* malloc or ne+6

Advanced Programming Techniques, Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

.tac, and heap sections

Function local data 52tac(6

D*namic memor* 5OAM6

D*namic glo%al data 5Geap6

2tatic glo%al data Program )ode

2tatic memor* 5O;M " OAM6

Advanced Programming Techniques, Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

!$

.amp e Use Case

Advanced Programming Techniques, Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

!#

Prob em 2i&e of the matri3 is not (no+n at compile time ;f course +e could assume a ma3imum num%er of elements, %ut this +ould spoil 5e3pensive6 memor*

Advanced Programming Techniques, Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

.ome ne* requirements /non-!unctiona 0 The si&e of the matri3 has to %e d*namic, i.e. it is defined during runtime )ertain operations are onl* supported for certain si&es

ImpactP

Advanced Programming Techniques, Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

!!

C malloc() and free() The malloc function is one of the functions in standard ) to allocate memor*. Its function protot*pe is void Qmalloc5si&eIt si&e6C +hich allocates size %*tes of memor*. If the allocation succeeds, a pointer to the %loc( of memor* is returned, else a null pointer is returned. Memor* allocated via malloc is persistent9 it +ill continue to e3ist until the program terminates or the memor* is e3plicitl* deallocated %* the programmer 5that is, the %loc( is said to %e RfreedR6. This is achieved %* use of the free function. Its protot*pe is void free5void Qpointer6C

Advanced Programming Techniques, Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

!/

C"" new and delete


In the )11 programming language, ne+ is an operator that allo+s d*namic memor* allocation on the heap for an* (ind of o%,ect incl. classes. 2*nta39 p_ ar = ne4 t%pename; ;; Beturn a t%ped pointer to the allocated memor% p_ ar = ne4 t%pename(>!; ;; Initialisation p_ ar = ne4 t%penameC#D; ;; Erra% )omparison +ith malloc Oeturns a t*ped pointer )alls the constructor 5primitive t*pes are not initiali&edH6 Krrors are handled via std..bad_alloc 5to %e detailed later6 Free memor*9 delete p_ ar; deleteCD p_ ar;
Advanced Programming Techniques, Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

Life Demo9 ))oordinate on heap


!"#$"# !0

Pointers1 address1 content1 dere!erencing


int Fp; p = ne4(int!; Fp = >; cout << 8p; cout << p; cout << Fp; ;; ;; ;; ;; ;; ;; ;; ;; ;; ;; <eclaration o7 a pointer to an integer Essigning memor% on the heap )toring the number > at the allocated memor% (he address o7 p on the heap (he content o7 p i.e. the start address o7 the allocated heap memor% (he dere7erenced content o7 the allocated memor%$ >

2tac( 5local Aaria%le6 Geap 5D*namic ;%,ect6

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

!4

2eap memor& and di!!erent data t&pes

;; :lobal section struct t4oints" int struct1; int struct2;+; int int1 = 1 struct t4oints s1; s1.struct1=1-; s1.struct2=11; struct t4ointsF ps1; struct t4ointsF ps2; ps1 = malloc(si3eo7(t4oints!!; ps1G>struct1=2-; ps1G>struct2=21; ps2 = ps1;

Adress $3#$$$ $3#$$/ $3#$$: $3#$$) $3#$#$ $3#$#/ $3#$#: $3#$#) $3#$ $ $3#$ / $3#$ : ...

Content int# B / s#.struct# B #$ s#.struct B ## ps# B $3#$ $ ps B $3#$ $

ps#-Sstruct# B $ ps#-Sstruct B #

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

!7

C ass Design

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

!:

Constructor Activit& Diagram

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

!=

Activit& Diagram 8asic diagram 2tarting point Knd point Activities Decisions Transitions

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

/$

Activit& Diagram K3tensions Toin and for( sho+ parallel activities K.g. tas(s in an ;2

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

/#

Activit& Diagram K3tensions 2+imlanes indicate processes 5e.g. client server6 2ignal receivers can %e used to sho+ messages 5net+or(, %et+een processes " threads of an ;26

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

Mapping Matri) in Memor& Pro%lem9 To store more comple3 data structure in memor*, a transformation has to %e defined

Logical structure

Ph*sical structure

$,$ $,# $, #,$ #,# #,

$,$ $,# $,

#,$ #,# #,
#$#4 #$ $

#$$$ #$$/ #$$: #$#

element address

address B offset 1 5elementIcolumn 1 columnIsi&e Q elementIro+6 Q elementIsi&e addres5#,#6 B PPP

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

/!

Constructor Code - incomp ete


m_si3e = m_ro4sFm_columns ; ;;Ellocate memor% 7or the matri, m_pErra% = ne4 doubleCm_si3eD; ;;(emporar% pointer 7or iterating through the arra% ;;9ote. 9e er change the ariable containing the start adress doubleF p=m_pErra% ; ;;Initiali3e the matri, s4itch (ini_mode! " case I9I(_H&B?). 7or (int I=- ; I<m_si3e; I@@! " Fp@@ = -.-; + breaI ; case I9I(_*9I(. 7or (int I=-; I<m_si3e; I@@! " Fp@@ = -.-; + ;;(his one onl% 4orIs 4ith Juadratic matrices i7 (m_ro4s == m_columns! " 7or (int I=-; I<m_columns; I@@! " F(m_pErra%@IFm_columns@I! = 1.- ; + breaI ; +

Transformation

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

//

Destructor
CKatri,..=CKatri,(! " cout << "<estructor " << m_count << endl ; ;;?ne element less m_countGG ; i7 (m_count == -!" s%stem("pause"! ; + deleteCD m_pErra% ; ;; 7ree allocated memor% +

-ith d*namic mem%ers, the destructor is mandator*H

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

/0

3e)t ecture4 Cop& Constructor Go+ are +e going to implement the cop* constructorP

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, adapted %* Prof. Dr.-Ing. M. Lipp

!"#$"#

/4

Wrap-Up Allocation of memor* for o%,ects This Pointer -rong initiali&ation of data is a common cause of programming errors )11 provides the follo+ing operations for initiali&ation of data )onstructor Destructor )op* )onstructor

Advanced Programming Techniques Prof. Dr.-Ing. P. Fromm, Prof. Dr.-Ing. M. Lipp

!"#$"#

/7

Anda mungkin juga menyukai