csc 330: class composition - computer sciencenatacha/teachspring_2013/csc330/cpp/lec4a... · csc...
TRANSCRIPT
CSC 330: Class composition
OutlineIntroduction
Initializing composite objects
Composite classes share objects?
Member initalization list
Objects as members of their own class?
Reference to objects
Pointers to objects
Static objects
Container class of components
Nested classes
Composition versus inheritance: a case study “Circle/Point”
Class composition 1
Constant data members: where to initialize
Class composition
Class composition means a class contains an object of adifferent class
A class that has objects of other classes as their datamembers are called composite classes
An object member of a class is called component object
The class of a component object is called component class
Member function of a composite class cannot access privatemembers of included objects
For example, a class Date would be composed of a Timeobject→ Class Date is a client (or user) of class Time
Class composition 2
Class composition: Date/Time
class Time {public :
void setTime ( int , i n t , i n t ) ;void pr in tT ime ( ) const ;
private :i n t hour , minute , second ;
} ;
class Date {public :
Date ( int , int , int , int , int , i n t ) ;void p r i n tDa te ( ) const ;
private :i n t day , month , year ;Time t ime ;
} ;
Class composition 3
Class composition: Date/Time
/ / Think how you would design i t b e t t e r ?Date : : Date ( i n t d , i n t m, i n t y , i n t sec , i n t min , i n t hour ) {
day = d ;month = m;year = y ;t ime . setTime ( sec , min , hour ) ;
}
void Date : : p r i n tDa te ( ) {cout << month << ’ / ’ << day << ’ / ’ << year << ’ ’ ;t ime . p r in tT ime ( ) ;
}
Can class Date access private members of class Time?
Class composition 4
Class composition: Point/Rectangle
/ / L i s t i n g 1 . a composite ob jec t w i t h wasted cons t ruc to r c a l l sclass Poin t {
private :i n t x , y ; / / p r i v a t e coord ina tes
public :Po in t ( i n t a=0 , i n t b=0) / /default cons t ruc to r
{x = a ; y = b ;cout << " Created : x= " << x << " y=" << y << endl ;
}. . . .
} ;
Class composition 5
Class composition: Point/Rectangle
class Rectangle { / / a composi t ion o f po in t s ?private :
Po in t pt1 , pt2 ; / / top− l e f t , bottom−r i g h t corner po in t si n t th i ckness ; / / th i ckness o f the rec tang le border
public :Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t width =1) ;. . .
} ;
Class composition 6
Testing Point/Rectangle
Poin t p1 (20 ,40) , p2 (70 ,90 ) ; / / top− l e f t , bottom−r i g h t cornersRectangle rec ( p1 , p2 , 4 ) ; / / cons t ruc t rec
/ / a l t e r n a t i v e l y ( bad choice )/ / c lass Rectangle / / a composi t ion o f po in t s ?/ / {/ / p r i v a t e :/ / i n t x1 , y1 , x2 , y2 ; / / top− l e f t , bottom−r i g h t corner po in t s/ / i n t th ickness ; / / th ickness o f the rec tang le border/ / p u b l i c :/ / Rectangle ( const i n t xx1 , const i n t yy1 ,
const i n t xx2 , const i n t yy2 , i n t width =1) ;
Class composition 7
Initializing composite objects
All data members could be specified in the memberinitialization list (MIL)
However,1. For members that are themselves class objects,
they should be initialized in the member initialization list2. Constant data members (including references) can only
be initialized inside the member initialization list
Object data members are first created before the compositeclass constructor is called
Class composition 8
Initializing composite objects
With wasted constructor calls/ / L i s t i n g 1 . composite ob jec t w i t h wasted cons t ruc to r c a l l sclass Poin t {
private :i n t x , y ; / / p r i v a t e coord ina tes
public :Po in t ( i n t a=0 , i n t b=0) / / genera l cons t ruc to r
{x = a ; y = b ;cout << " Created : x= " << x << " y=" << y << endl ;
}Po in t ( const Poin t& pt ) / / copy cons t ruc to r
. . .void operator = ( const Poin t& pt ) / / assignment opera tor
. . .. . . . .
} ;
Class composition 9
Initializing composite objects
Wasted callsclass Rectangle {
private :Po in t pt1 , pt2 ; / / top− l e f t , bottom−r i g h t corner po in t si n t th i ckness ; / / th i ckness o f the rec tang le border
public :Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t width =1) ;. . . .
} ;
Rectangle : : Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t width ){ pt1 = p1 ; pt2 = p2 ; th ickness = width ; } / / se t data members
Class composition 10
Initializing composite objects
Wasted callsPoin t p1 (20 ,40) , p2 (70 ,90 ) ;/ / 1 . p1 and p2 created , Po in t genera l cons t ruc to r c a l l e d
Poin t p o i n t (100 ,120) ;/ / 2 . po i n t i s created , Po in t genera l cons t ruc to r c a l l e d
Rectangle rec ( p1 , p2 , 4 ) ;/ / 3 . Creat ion o f Rectangle ob jec t rec/ / 3 . 1 . c rea t i on o f pt1 and pt2 , c a l l i n g Po in t d e f a u l t cons t ruc to rs/ / Note : Po in t d e f a u l t cons t ruc to rs are c a l l e d before the/ / the Rectangle ob jec t i s created !/ / 3.2 assignment opera tor i s c a l l e d
Class composition 11
Initializing composite objects
Wasted calls
→ For large composite objects, the process of creation canbecome quit wasteful. What to do?
The solution: Member initialization list (MIL)
Rectangle : : Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t w): th ickness (w) , pt1 ( p1 ) , pt2 ( p2 ) / / i n i t i a l i z a t i o n l i s t
{ } / / empty member body
Class composition 12
Initializing composite objects
Saving calls/ / L i s t i n g 2 . A composite ob jec t w i t hou t wasted cons t ruc to r c a l l sclass Poin t {
private :i n t x , y ; / / p r i v a t e coord ina tes
public :Po in t ( i n t a=0 , i n t b=0) / / genera l cons t ruc to r
{x = a ; y = b ;cout << " Created : x= " << x << " y=" << y << endl ;
}Po in t ( const Poin t& pt ) / / copy cons t ruc to r
. . .void operator = ( const Poin t& pt ) / / assignment opera tor
. . .. . . .
} ;
Class composition 13
Initializing composite objects
Saving callsclass Rectangle {
private :Po in t pt1 , pt2 ; / / top− l e f t , bottom−r i g h t corner po in t si n t th i ckness ; / / th i ckness o f the rec tang le border
public :Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t width =1) ;. . .
} ;
/ / Be t t e r choice : copy cons t ruc to r c a l l sRectangle : : Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t w)
: th ickness (w) , pt1 ( p1 ) , pt2 ( p2 ) / / i n i t i a l i z a t i o n l i s t{ } / / empty member body
Class composition 14
Initializing composite objects
Saving callsPoin t p1 (20 ,40) , p2 (70 ,90 ) ;/ / 1 . p1 and p2 created , Po in t genera l cons t ruc to r c a l l e d
Poin t p o i n t (100 ,120) ;/ / 2 . po i n t i s created , Po in t genera l cons t ruc to r c a l l e d
Rectangle rec ( p1 , p2 , 4 ) ;/ / 3 . Creat ion o f Rectangle ob jec t rec/ / 3 . 1 . pt1 and pt2 created , Po in t copy cons t ruc to r c a l l e d/ / 3.2 No assignment opera tor i s c a l l e d ! Saving !
Class composition 15
Initializing composite objects
Summary
The purpose of the member initialization list is to avoida call to the default constructor of the component classbefore the call to the composite class constructor
The member initialization list replaces the call
to the default constructor of the component class
with the call to the constructor specified in the initialization list
Class composition 16
Outline
Introduction
Initializing composite objects
Constant data members: where toinitialize
Composite classes share objects?
Member initalization list
Objects as members of their own class?
Reference to objects
Pointers to objects
Static objects
Container class of components
Nested classesComposition versus inheritance: a case study “Circle/Point”
Class composition 17
Constant variable?
Many usage of "const":const i n t x ; / / constant i n tx = 2; / / i l l e g a l − can ’ t modify x
const i n t ∗ pX ; / / changeable p o i n t e r to constant i n t∗pX = 3; / / i l l e g a l − can ’ t use pX to modify an i n tpX = &someOtherIntVar ; / / l e g a l − pX can po in t somewhere else
i n t ∗ const pY ; / / constant p o i n t e r to changeable i n t∗pY = 4; / / l e g a l − can use pY to modify an i n tpY = &someOtherIntVar ; / / i l l e g a l − can ’ t make pY po in t anywhere e lse
const i n t ∗ const pZ ; / / const p o i n t e r to const i n t∗pZ = 5; / / i l l e g a l − can ’ t use pZ to modify an i n tpZ = &someOtherIntVar ; / / i l l e g a l − can ’ t make pZ po in t anywhere e lse
Class composition 18
Constant variable?
i n t y ;const i n t ∗ pConstY = &y ; / / l e g a l − but can ’ t use pConstY to modify yi n t ∗ pMutableY = &y ; / / l e g a l − can use pMutableY to modify y∗pMutableY = 42;
const i n t x ; / / x cannot be modi f ied
const i n t ∗ pX = &x ; / / pX i s the address o f a const i n t/ / and can ’ t be used to change an i n t
∗pX = 4; / / i l l e g a l − can ’ t use pX to change an i n t
i n t ∗ p I n t ; / / address o f normal i n tp I n t = pX ; / / i l l e g a l − cannot conver t from const i n t ∗ to i n t ∗
i n t ∗ p I n t ; / / address o f a normal i n tp I n t = &x ; / / i l l e g a l − cannot conver t from const i n t ∗ to i n t ∗
Class composition 19
Constant data members
Where to initialize?
What is common in the following data?account number, employee date of hire, price paid, ID, weightof one unit of area
How often they change? Does it make sense to changethem?
Recall: with const int x=10;x cannot be assigned any value later
In analogy: a constant data memberhas to be initialized immediately after it is created
How can we do it?
Class composition 20
Constant data members
Member initialization listclass Rectangle {
private :Po in t pt1 ;Po in t pt2 ;i n t th i ckness ;const double weight ; / / weight o f one u n i t o f area
public :Rectangle ( const Poin t& p1 , const Poin t& p2 , double wt , i n t width =1) ;
. . . .} ;
Rectangle : : Rectangle ( const Poin t& p1 , const Poin t& p2 , double wt , i n t width ): th ickness ( width ) , pt1 ( p1 ) , pt2 ( p2 ) , weight( wt )/ / i n i t i a l i z a t i o n o f weight ( wt ) here s mandatory
{ }
Class composition 21
Constant data members
Another exampleclass MyClass {
private :i n t hours ; / / I s ’ hours ’ declared here?i n t minutes ;const i n t s ize ;
public :MyClass ( i n t h , i n t m, i n t s )
: hours ( h ) , minutes (m) , s ize ( s ) / / member i n i t i a l i z a t i o n l i s t{ }
void p r i n t ( ) const{
cout << " your c lass data are \ n " ;cout << " Hours : " << hours << ’ ’
<< " Minutes : " << minutes << ’ ’ << " Size : " << s ize << endl ;}
Class composition 22
Constant data members
void set ( i n t a , i n t b , i n t c ) {/ / s i ze=a ; / / ∗∗∗TRY IT ∗∗∗∗ : uncomment t h i s l i n e to t e s t/ / so you want to change s ize ?/ / Well , s ince s ize i s constant the compi ler w i l l not l e t t h i s go/ / cons t_ tes t . cpp : 5 6 : assignment o f read−only member ‘ MyClass : : s i ze ’hours = b ;minutes = c ;
}
void operator = ( const MyClass &c ) {hours = c . hours ;minutes=c . minutes ;/ / s i ze = c . s ize ; / / ∗∗∗TRY IT ∗∗∗∗ : uncomment t h i s l i n e to t e s t/ / the compi ler w i l l not agree ! ! s i ze i s const => cannot be changed !/ / E r ro r : assignment o f read−only member ‘ MyClass : : s i ze ’
}} ; / / end c lass
Class composition 23
Constant data members
MyClass mc(5 ,10 ,60 ) ;/ / w i th t h i s you are dec la r i ng & i n i t i a l i z i n g/ / the ob jec t mc i n c l u d i n g hours , minutes and s ize ./ / They are being created ( " cons t ruc ted " ) w i th a s p e c i f i e d value ./ / Thus they are being i n i t i a l i z e d . I f you change t h e i r/ / value l a t e r w i th opera tor = t h a t i s an assignment ./ / l i k e mc=mc1 ;mc. p r i n t ( ) ; / / p r i n t s 5 ,10 ,60mc. set ( 6 , 5 , 7 ) ;mc. p r i n t ( ) ; / / p r i n t s 6 ,5 ,60
MyClass mc1(15 ,20 ,70) ;/ / so you want to assign mc1 to mc/ / t h i s imp l i es you would change the const data member s ize ! ! !mc=mc1 ; / / s i ze i s not / cannot be changed !mc. p r i n t ( ) ; / / p r i n t s 15 ,20 ,60
Class composition 24
Composite classes share objects?
Can a data member of a class be shared by two composite classobjects?
|−−−−−|| ||−−−−−x−−−−−−−| 2 po in t s o f a rec tang le shared wi th two other ob jec ts
| ||−−−−−−−x−−−−−−|
|−−−−−−|
An object can be shared using reference or pointer to an object
Class composition 25
Outline
Introduction
Initializing composite objects
Constant data members: where toinitialize
Composite classes share objects?
Member initalization list
Objects as members of their own class?
Reference to objects
Pointers to objects
Static objects
Container class of components
Nested classesComposition versus inheritance: a case study “Circle/Point”
Class composition 26
Reference data members
Recall: all references in C++ are constant:1. they cannot change after they are initialized2. but their content can change
Hence,reference data members must be initialized only in a memberinitialization list
Note:Point& pt1;→ pt1 is a reference (an alias) that cannot change but itscontent can be changedconst Point& pt1;→ pt1 is a reference that cannot change; its contentscannot change either
Class composition 27
Reference data members: Example
class Rectangle {private :
Po in t& pt1 ; / / shared : re ference cannot be changedPoin t& pt2 ; / / shared : re ference cannot be changedi n t th i ckness ; / / th i ckness o f the rec tang le borderconst double weight ; / / weight o f one u n i t o f area
public :Rectangle ( const Poin t& p1 , const Poin t& p2 , double wt , i n t width =1) ;. . . .
} ;
Class composition 28
Reference data members: Example
Rectangle : : Rectangle ( const Poin t& p1 , const Poin t& p2 , double wt , i n t width ): pt1 ( p1 ) , pt2 ( p2 ) , weight ( wt )
/ / pt1 ( p1 ) i s mandatory because r e f i s constant{ th ickness=width ; }
Q: What about the rightmost parameters in a constructor?Can you tell what is wrong with ...
Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t width =1 , double wt ) ;/ / H in t : Rectangle R( p1 , p2 , width , wt ) ; or Rectangle R( p1 , p2 , wt , width ) ;
Class composition 29
Pointers members of composite classes
class Rectangle {private :
Po in t ∗pt1 ; / / can be shared and changedPoin t ∗pt2 ;i n t th i ckness ; / / th i ckness o f the rec tang le borderconst double weight ; / / weight o f one u n i t o f area
public :Rectangle ( const Poin t∗ p1 , const Poin t∗ p2 , double wt , i n t width =1) ;. . . .
} ;
Rectangle : : Rectangle ( const Poin t∗ p1 , const Poin t∗ p2 , double wt , i n t width ): th ickness ( width ) , pt1 ( p1 ) , pt2 ( p2 ) , weight ( wt )
/ / pt1 ( p1 ) not mandatory here/ / Note : pt1 ( p1 ) i s p o i n t e r i n i t i a l i z a t i o n −− not copy cons t ruc to r/ / You may pass Po in te rs as not const ; Then they can be changed{ }
Class composition 30
Pointers members of composite classes
Poin t∗ p= new Poin t (20 ,40 ) ;Po in t∗ q=new Poin t (70 ,90 ) ;
Rectangle rec ( p , q , 4 ) ;/ / 3 . Creat ion o f Rectangle ob jec t rec/ / 3 . 1 . pt1 and pt2 po in te r s are assigned They Po in t to p and q .
Class composition 31
Outline
Introduction
Initializing composite objects
Constant data members: where toinitialize
Composite classes share objects?
Member initalization list
Objects as members of their own class?
Reference to objects
Pointers to objects
Static objects
Container class of components
Nested classesComposition versus inheritance: a case study “Circle/Point”
Class composition 32
Member initialization list
Mandatory:
Constant data memebrs including references (which areconstant), constant pointers, ...
Call to base class constructor
Reference to a component object
Prefered:
Initialize component objects(i.e., objects as member of other classes)it saves extra calls
Optional:
A pointer to a component object
Other data members (non-static)Class composition 33
Member initialization list
Practical programmers:
emphasize initializing ALL data members in ALL constructors(primitive or user-defined)
initalize most of the data memebrs in the MIL
initialzie data members IN ORDER of declaration unless youABSOLUTELY cannot (see example below)
Class composition 34
Member initialization list
Examples of the “absolutely cannot”
When the initialization procedure is complexdata = new Sample ∗ [MAX_ELEMENT ] ; / / Two dimensional a r rayfor ( unsigned i n t i = 0 ; i < MAX_ELEMENT ; i ++)data [ i ] = new Sample [MAX_ELEMENT ] ;
When there is an important comment to make before aparticular initialization line
His to r y ( ) : s i ze ( 3 ) , count ( 0 ) , i dx ( 0 ) {/ / The f o l l o w i n g l i n e i s the source o f BUG 3876data = new Sample [MAX_ELEMENT ] ;i f ( data == NULL) {cout << ’ ’No memory a l l o c a t e d ’ ’ <<endl ; e x i t ( 1 ) ;
}cout << ’ ’ user created defaul t cons t ruc to r o f H i s to r y c a l l e d ’ ’ <<endl ;
}
Class composition 35
Outline
Introduction
Initializing composite objects
Constant data members: where toinitialize
Composite classes share objects?
Member initalization list
Objects as members of their own class?
Reference to objects
Pointers to objects
Static objects
Container class of components
Nested classesComposition versus inheritance: a case study “Circle/Point”
Class composition 36
Objects as members of their own class?
Recall:
Data members are allocated in the order in which they arelisted in the class declaration
Static data (members) are one time allocated at the beginningof program execution
Static data (members) are destroyed after the programterminate
Class composition 37
Objects as members of their own class?
/ / An ob jec ts as member o f i t s own c lassclass Poin t {
private :i n t x , y ; / / p r i v a t e coord ina tesPoin t o r i g i n ; / / can I do t h i s ?
. . .} ;
Po in t p ; / / P i s created means/ / memory f o r x and y i s a l l o c a t e d/ / memory f o r o r i g i n i s a l l o c a t e d/ / memory f o r x and y of o r i g i n i s a l l o c a t e d/ / memory f o r o r i g i n o f o r i g i n i s a l l o c a t e d . ./ / . . . e tc . i n f i n i t e recu rs i ve loop !
→ (non-static) objects as members of their own class aredisallowed
Class composition 38
Reference to objects as members of their own class?
/ / An ob jec ts as member o f i t s own c lassclass Poin t {
private :i n t x , y ; / / p r i v a t e coord ina tesPoin t &o r i g i n ; / / can I do t h i s ?
public :Po in t ( Po in t &org , i n t a=0 , i n t b=0) : o r i g i n ( org ){ x=a ; y=b ; } / / o r i g i n ( org ) mandatory
. . .} ;
Class composition 39
Reference to objects as members of their own class?
Poin t ∗p=0; / / p set to n u l lPoin t ∗p = new Poin t (∗p , 8 0 , 9 0 ) ; / / a l l o c a t e memory and set to 80 ,90Poin t p1 ( p ) ; / / ∗p i s used as the o r i g i n f o r p1
→ Do not use (non-static) objects as members of their own classunless you have toBut what is the solution then?
Class composition 40
Static objects as members of their own class
/ / L i s t i n g 3 Using s t a t i c data members and a s t a t i c member f u n c t i o n .class Poin t {
private :i n t x , y ; / / p r i v a t e coord ina tess t a t i c i n t count ;s t a t i c Poin t o r i g i n ;
public :Po in t ( i n t a=0 , i n t b=0) / / genera l cons t ruc to r
{x = a ; y = b ; count ++;cout << " Created : x=" << x << " y=" << y
<< " count= " << count << endl ;}
Class composition 41
Static objects as members of their own class
s t a t i c i n t q u a n t i t y ( ) / / const i s not al lowed{ return count ; }
. . .~Po in t ( ) { / / d e s t r u c t o r
count−−;cout <<" Po in t destroyed : x=" <<x <<" y=" <<y <<endl ;
}} ;
Class composition 42
Static objects as members of their own class
i n t Poin t : : count = 0 ; / / i n i t i a l i z a t i o nPoin t Po in t : : o r i g i n (640 ,0 ) ; / / i n i t i a l i z a t i o n/ / ou tput : ’ Created : x=640 y=0 count =1 ‘
cout << " Number o f po in t s : " << Po in t : : q u a n t i t y ( ) << endl ;/ / ou tput : Number o f po in t s : 1
Poin t p1 , p2 (30 ) , p3 (50 ,70 ) ;/ / ou tput : 0 ,0 ,2 30 ,0 ,3 and 50 ,70 ,4
cout << " Number o f po in t s : " << p1 . q u a n t i t y ( ) << endl ;/ / ou tput : number o f po in t s : 4/ / Output from hidden c a l l s :/ / destroyed 50 ,70 destroyed 30 ,0 destroyed 0 ,0/ / But why ‘ destroyed 640 ,0 ’ i s not output ?/ / ==> s t a t i c data are destroyed a f t e r the program termina te
Class composition 43
A note to return types
Any difference between:1. Polynomial Polynomial::operator = (Polynomial& p);//with return *this;2. Polynomial& Polynomial::operator = (Polynomial& p);//with return *this
There is a BIG difference!
Without the ’&’ a copy of the object to be returned is made,and this copy is subsequently returned
With the ’&’ you are returning a reference to the object, whichsimply means you are not making a copy of the object toreturn
There are several implications related to thisClass composition 44
Outline
Introduction
Initializing composite objects
Constant data members: where toinitialize
Composite classes share objects?
Member initalization list
Objects as members of their own class?
Reference to objects
Pointers to objects
Static objects
Container class of components
Nested classesComposition versus inheritance: a case study “Circle/Point”
Class composition 45
Class composition: container class
class Rectangle {private :
Po in t pt1 , pt2 ; / / top− l e f t , bottom−r i g h t corner po in t si n t th i ckness ; / / th i ckness o f the rec tang le border
public :Rectangle ( const Poin t& p1 , const Poin t& p2 , i n t width =1) ;
. . . .} ;
Rectangle conta ins a f i x e d c o l l e c t i o n o f components : two
A container class includes a ‘dynamically’ created collectionof components
Useful: when we need a data type that contains a dynamiccollection of values
How often we need such thing?Class composition 46
Class composition: container class
While the program executes, we would like to add moreobjects to the container
Why? for temporary storage or for processing
Example:Container class: customer charge accountcomponents: customer credit card transactions to beprocessedProcessing: totals, taxes, printing, reports, searching, etc.
But why not using an array for that?
Class composition 47
Class composition: container class
With an array we cannot perform high level tasks such asaddition, search, validation, setting values of subcomponents, checking the index, etc.
Container classes are designed to perform these operation forthe client code
The client code does not need to deal with low-levelimplementations
Class composition 48
Container classes: an example
For simplicity: a Sample component class with one datamember
The Sample objects are produced for example by a stockexchange ticker tape, a patient monitoring device, or apressure observation.
For simplicity, we assume the values for the Sample class arehard-coded in an array
Class composition 49
Container classes: an example
/ / L i s t i n g 4 A con ta ine r c l ass w i t h dynamical ly−al l o c a t e d memory
class Sample { / / component c lassprivate :double value ; / / sample value
public :Sample ( double x = 0) / / d e f a u l t and convers ion cons t ruc to r
{ value = x ; }void set ( double x ) / / mod i f i e r method
{ value = x ; }double get ( ) const / / s e l e c t o r method
{ return value ; }} ;
Class composition 50
Class composition: container class
class His to r y { / / con ta ine r c lass : set valueprivate :
i n t size , count , i dx ;Sample ∗data ; / / could be an ar ray o f data
public :H i s to r y ( ) : s i ze ( 3 ) , count ( 0 ) , i dx ( 0 ) / / make ar ray empty
{data = new Sample [ s ize ] ; / / a l l o c a t e new spacei f ( data == NULL)
{ cout << " Out o f memory \ n " ; e x i t ( 1 ) ; }}
~ H i s to r y ( ) { delete [ ] data ; } / / f r ee dynamic memory
Note: Since "Sample *data" is not a constant it must not beinitialize in the MIL
Class composition 51
Class composition: container class
void add ( double ) ; / / add a sample a t the end
Sample& getComponent ( ) / / r e t u r n re ference to Sample{ return data [ i dx ] ; } / / can be a message t a r g e t
void g e t F i r s t ( ) { i dx = 0; }bool getNext ( ) { return ++ idx < count ; }void average ( ) const ; / / p r i n t average
} ;
Class composition 52
Class composition: container class
void His to r y : : add ( double s ) {i f ( count == s ize ) {
s ize = s ize ∗ 2; / / double s ize i f out o f spaceSample ∗p = new Sample [ s ize ] ;i f ( p == NULL)
{ cout << " Out o f memory \ n " ; e x i t ( 1 ) ; } / / t e s t f o r successfor ( i n t i =0; i < count ; i ++)
p [ i ] = data [ i ] ; / / copy e x i s t i n g elementsdelete [ ] data ; / / de le te e x i s t i n g ar raydata = p ; / / rep lace i t w i th new ar raycout << " new s ize : " << s ize << endl ; / / debugging p r i n t
}data [ count ++ ] . se t ( s ) ; / / use next space a v a i l a b l e
}
Class composition 53
Class composition: container class
void His to r y : : average ( ) const {cout << " \ n Average value : " ;double sum = 0;for ( i n t i = 0 ; i < count ; i ++)
sum += data [ i ] . get ( ) ;cout << sum / count << endl ;
}
Class composition 54
Testing container class
double a [ ] = {3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 } ; / / i npu t dataHis to r y h ;for ( i n t i =0; i < 9 ; i ++)
h . add ( a [ i ] ) ; / / add h i s t o r ycout << " \ n Measurement h i s t o r y : " << endl << endl ;h . g e t F i r s t ( ) ; / / work i s pushed updo {
cout << " " << h . getComponent ( ) . get ( ) ;/ / p r i n t each component
} while ( h . getNext ( ) ) ;h . average ( ) ;
/ / Output :new s ize : 6new s ize : 12Measurement h i s t o r y : 3 5 7 11 13 17 19 23 29Average : 14.1111
Class composition 55
Container classes
Container classes with more complex design includesorting, search, removal, insertion, update, comparison
A significant number of container classes are availablefrom the Standard Template Library
Class composition 56
Nested classes
In C++, we can define a server class inside a client class
This way the nested class name is not visible outside of thecomposite class
Nested class definitions can appear in either the private orpublic section
In both cases Nested class is hidden from the rest of theprogram
Nested class cannot be used to declare variables of its type inother scopes outside the composite class
Class composition 57
Nested classes
class His to r y {private :
class Sample{ / / component c lass
private :double value ; / / sample value
public :Sample ( double x = 0) / / d e f a u l t and convers ion cons t ruc to r
{ value = x ; }void set ( double x ) / / mod i f i e r method
{ value = x ; }double get ( ) const / / s e l e c t o r method
{ return value ; }} ;
i n t size , count , i dx ;Sample ∗data ;
Class composition 58
Nested classes
public :H i s to r y ( ) : s i ze ( 3 ) , count ( 0 ) , i dx ( 0 ) { / / make ar ray empty
data = new Sample [ s ize ] ; / / a l l o c a t e new spacei f ( data == NULL)
{ cout << " Out o f memory \ n " ; e x i t ( 1 ) ; }}. . . .
} ;
/ / Usedouble a [ ] = {3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 } ; / / i npu t data
His to r y h ;for ( i n t i =0; i < 9 ; i ++)
h . add ( a [ i ] ) ; / / add h i s t o r y. . .Sample s =5; / / OK?His to r y : : Sample s =5; / / OK? when?
Class composition 59
Outline
Introduction
Initializing composite objects
Constant data members: where toinitialize
Composite classes share objects?
Member initalization list
Objects as members of their own class?
Reference to objects
Pointers to objects
Static objects
Container class of components
Nested classesComposition versus inheritance: a case study “Circle/Point”
Class composition 60
Composition or inheritance?
Composition: the existence of a "has-a" relationshipaggregate objects in a class
Inheritance: the existence of a “is-a” relationship conceptuallyconnect classes in an inheritance hierarchy
In most problems, inheritance is very useful and should beoften considered, however,
Inheritance forces the client programmer to learn aconsiderable amount about the server design, speciallywhen the hierarchy is tallDependencies between classes in inheritance are verystrong
Class composition 61
Composition or inheritance?
Composition is conceptually simpler & links between classesare not as strong
Composition is, in general, easier to maintain
Choice depends on degree of similarity between relatedclasses
If the number of common methods is small & the number ofmethods to be is large, composition is a good alternative
If a “is-a” relationship is not clear then use composition:A Rectangle "has a" Point but it is not a Point;A Cylinder "has a" Circle or "is a" Circle?An Address "is a" Name or "has a" Name?
Class composition 62
Circle/Cylinder: composition
/ / L i s t i n g 5 code reuse through c lass composi t ionclass C i r c l e { / / o r i g i n a l code f o r reuse
protected : / / i n h e r i t a n c e i s one of the opt ionsdouble rad ius ; / / i n t e r n a l data
public :s t a t i c const double PI ; / / i t must be i n i t i a l i z e dC i r c l e ( double r ) ; / / convers ion cons t ruc to rdouble getLength ( ) const ; / / compute c i rcumferencedouble getArea ( ) const ; / / compute areadouble getRadius ( ) const ;void set ( double r ) ; / / change s ize
} ;const double C i r c l e : : PI = 3.1415926536;
Class composition 63
Circle/Cylinder: composition
class Cy l inder { / / new c lass Cy l inderprotected :
C i r c l e c ; / / no PI , no rad iusdouble he igh t ; / / new code
public :Cy l inder ( double r , double h ) : c ( r ) / / i n i t i a l i z e r l i s t ( no PI )
{ he igh t = h ; }double getLength ( ) const { return c . getLength ( ) ; } / / from c lass C i r c l edouble getRadius ( ) const { return c . getRadius ( ) ; } / / from c lass C i r c l evoid set ( double r ) { c . se t ( r ) ; } / / from c lass C i r c l edouble getVolume ( ) const / / no getArea ( )
{double rad ius = c . getRadius ( ) ;return C i r c l e : : PI ∗ rad ius ∗ rad ius ∗ he igh t ;
}} ;
Class composition 64
Circle/Cylinder: composition
i n t main ( ) {Cy l inder cy l1 ( 2 . 5 , 6 . 0 ) , cy l2 ( 5 . 0 , 7 . 5 ) ; / / i n i t i a l i z e datadouble l eng th = cy l1 . getLength ( ) ; / / s i m i l a r to C i r c l ecy l1 . se t ( 3 . 0 ) ;double diam = 2 ∗ cy l1 . getRadius ( ) ; / / no c a l l to getArea ( )double vo l = cy l2 . getVolume ( ) ; / / not i n C i r c l ecout << " Circumference of f i r s t c y l i n d e r : " << leng th << endl ;cout << " Volume of the second c y l i n d e r : " << vo l << endl ;cout << " Diameter o f the f i r s t c y l i n d e r : " << diam << endl ;return 0;}
Class composition 65
Circle/Cylinder: inheritance
/ / L i s t i n g 6 code reuse through i n h e r i t a n c eclass C i r c l e { / / o r i g i n a l code f o r reuse
protected : / / i n h e r i t a n c e i s one of the opt ionsdouble rad ius ; / / i n t e r n a l data
public :s t a t i c const double PI ; / / i t must be i n i t i a l i z e dC i r c l e ( double r ) ; / / convers ion cons t ruc to rdouble getLength ( ) const / / compute c i rcumference
{ return 2 ∗ PI ∗ rad ius ; }double getArea ( ) const ; / / compute areadouble getRadius ( ) const ;void set ( double r ) ; / / change s ize
} ;const double C i r c l e : : PI = 3.1415926536;
Class composition 66
Circle/Cylinder: inheritance
class Cy l inder : public C i r c l e { / / new c lass Cy l inderprotected :
double he igh t ; / / o ther data i s i n C i r c l epublic :
Cy l inder ( double r , double h ) : C i r c l e ( r ) / / i n i t i a l i z e r l i s t ( no PI ){ he igh t = h ; } / / new code
double getVolume ( ) const / / no getArea ( ){ return he igh t ∗ getArea ( ) ; } / / a d d i t i o n a l c a p a b i l i t y
} ;
Class composition 67
Circle/Cylinder: inheritance
i n t main ( ) {Cy l inder cy l1 ( 2 . 5 , 6 . 0 ) , cy l2 ( 5 . 0 , 7 . 5 ) ; / / i n i t i a l i z e datadouble l eng th = cy l1 . getLength ( ) ; / / s i m i l a r to C i r c l ecy l1 . se t ( 3 . 0 ) ;double diam = 2 ∗ cy l1 . getRadius ( ) ; / / no c a l l to getArea ( )double vo l = cy l2 . getVolume ( ) ; / / not i n C i r c l ecout << " Circumference of f i r s t c y l i n d e r : " << leng th << endl ;cout << " Volume of the second c y l i n d e r : " << vo l << endl ;cout << " Diameter o f the f i r s t c y l i n d e r : " << diam << endl ;return 0;
}
Class composition 68
Review
class Rectangle {private :
Po in t p ;. . .
}/ / which Const ruc torRectangle ( Po in t& q , . . . ) { p=q ; . . . } / / = d e f a u l t cons t r . +assignment op/ / orRectangle ( Po in t& q , . . . ) : p ( q ) { . . . } / / copy cons t ruc to r
/ / What i s i n a member i n i t i a l i z a t i o n l i s t ?
Class composition 69