Advanced Issues on Classes - PowerPoint PPT Presentation

1 / 38
About This Presentation
Title:

Advanced Issues on Classes

Description:

constructor, destructor, copy constructor, deep copy, assignment operator ... 'cherry'); cout 'a : '; Print(a); //cherry apple ... (b); //cherry apple 2 ... – PowerPoint PPT presentation

Number of Views:67
Avg rating:3.0/5.0
Slides: 39
Provided by: berrinya
Category:

less

Transcript and Presenter's Notes

Title: Advanced Issues on Classes


1
Advanced Issues on Classes
  • Part 1 (2hrs)
  • -sharing a variable among several objects of the
    same class (reference variables, pointers)
  • iterators
  • Part 2 (3hrs)
  • constructor, destructor, copy constructor, deep
    copy, assignment operator
  • operator overloading
  • Horton pp.334... (a bit better, more compact)
  • Appendix E in Tapestry

2
(destructor, constructor reminder)copy
constructor, deep copy
3
Destructor reminder Tapestry pp. 625
  • Each class should also have a destructor which
    should take care of returning any unreturned
    memory.
  • The destructor has name classname similar to
    that of the constructor
  • e.g. linkedlist()
  • The destructor is called automatically when
  • the object goes out of scope or
  • the programmer deletes the object

4
DestructorTapestry pp. 624
  • int CountUnique (ifstream input)
  • string word
  • LinkStringSet set //similar to
    linkedlistltstringgt
  • while (input gtgt word) //by inserting words into
    a set which
  • set.insert(word) //skips the insertion if the
    element is already in the set
  • //we can count how many elements (words) are
    unique
  • return set.size
  • What happens to set when this function returns?

5
DestructorTapestry pp. 624
  • When a class instance goes out of scope, the
    class destructor is automatically called
  • e.g. for the LinkStringSet object in the prev.
    slide
  • Since the compiler makes this call automatically,
    it creates a a dummy destructor for each class
    that does not contain a destructor. So,
  • if the programmer has not supplied a destructor,
    the one which is created by the compiler is
    called
  • This basically prevents the program from
    crashing, but as a dummy function, it is not
    guaranteed to do the right thing (e.g. doesnt
    free all memory)
  • if the programmer has supplied one, compiler
    wont generate a dummy destructor
  • Remember that the (real) destructor should free
    all memory taken with new
  • LinkStringSetLinkStringSet()
  • reclaimnodes(myhead)
  • myhead 0

6
Copy Constructor
  • Special constructor called when an object is
    first defined and initialized from another object
    of the same type
  • Example
  • LinkedList list3(list)
  • Date today
  • Date tomorrow (today1)
  • Date yesterday (today-1)
  • //Date yesterday tomorrow //this is not a
    copy constructor
  • Syntax
  • linkedlistlinkedlist (const linkedlist l)
  • datedate (const date d)

7
Copy Constructor Example
  • LinkedList list1
  • list1.InsertOrdered(7)
  • list1.PrintList()
  • list1.InsertOrdered(4)
  • list1.PrintList()
  • LinkedList list2(list1)
  • list2.PrintList()
  • list1.DeleteList()
  • list2.PrintList() //We want to be able to do
    this!

8
Copy Constructor
  • For every class, there is a default copy
    constructor (compiler provided)
  • Simply copies the value of each instance variable
    from one object to the other.
  • Default copy constructor can only do a shallow
    copy only the private data of a class instance
    is copied.
  • In the case of a linked list, this would be the
    head pointer, NOT the whole list
  • The new list share the same memory as the old
    one!
  • what can we do if we want what is called a deep
    copy (make a copy of the nodes etc. too)
  • e.g. LinkedList list2(list1)

9
Shallow Copy
  • If you say
  • list2 list1
  • This is what happens

list1 3 4
5
list2
10
Deep Copy
  • If you want to be able to assign objects like
    lists, you want to copy the whole list to another
    object
  • hence the name deep copy
  • you must provide a proper copy constructer for
    your class (using the compilers dummy version is
    not enough)
  • LinkedList list2(list1)

list1 3 4
5
list2 3 4
5
11
Deep Copy How?
  • e.g. LinkedStringSet list2(list1)
  • LinkStringSetLinkStringSet (const
    LinkStringSet set)
  • myFirst(new Node("header",set.clone())),
    //same as myFirst new Node("header",set.clone()
    ))
  • mySize(set.size()) //see the color
    illustration below
  • // deep copy made in an initializer list
  • The newly created object is calling a helper
    function called clone()
  • Shown in the next slides
  • Remember private variables and functions can be
    accessed by objects of the same class (or by
    friend classes)

list2.myFirst 3 4
5 list1.myFirst
header
3 4 5
.
12
  • LinkStringSetNode LinkStringSetclone()
    const
  • Node front("front",0)
  • Node last front
  • Node temp myFirst-gtnext
  • while (temp ! 0)
  • last-gtnext new Node(temp-gtinfo,0)
  • last last-gtnext
  • temp temp-gtnext
  • return front.next

13
Operator Overloading
14
Assignment Operator
  • Lets overload (make it work for your own class)
    the assignment operator.
  • Syntax const foo foooperator (const foo
    f)
  • e.g. const linkedlist linkedlistoperato
    r (const linkedlist l)
  • Usage list2 list1
  • Compiler interprets this as list2.operator(list1
    )
  • Similar to the copy constructor, but the
    assignment operator is called to reinitialize an
    object that has already been constructed.
  • Since the object already exists, more bookkeeping
    is necessary

15
  • LinkedList list, l3
  • ...
  • list.InsertOrdered(7)
  • list.PrintList()
  • list.InsertOrdered(4)
  • list.PrintList()
  • ...
  • LinkedList list2(list) //copy constructor
    list2(list)
  • list2.PrintList()
  • list3 list //assignment op.
    l3.operator(list)
  • list3.PrintList()
  • list.DeleteList()
  • list2.PrintList()
  • list3.PrintList()

16
Assignment Operator
  • const foo
  • foooperator (const foo f)
  • const LinkStringSet
  • LinkStringSetoperator (const LinkStringSet
    set)
  • if (set ! this) //this is a pointer each
    object has to itself
  • reclaimNodes(myFirst-gtnext) //this is b
  • myFirst-gtnext set.clone() //copy a
  • mySize set.size()
  • return this //return b
  • ...
  • //Usage of the assgnmnt. operator
  • b a //b will represent a different object
    than before

17
Assignment Operator explanation
  • const LinkStringSet
  • LinkStringSetoperator (const LinkStringSet
    set)
  • if (set ! this) //to prevent misbehaviour
    if aa is used
  • reclaimNodes(myFirst-gtnext) //free
    memory of rhs
  • myFirst-gtnext set.clone() //copy lhs
  • mySize set.size()
  • return this //return rhs for situations
    when
  • //a b c is used
  • //which is equal to the statement
  • //a (b c)
  • b a

18
  • LinkStringSetLinkStringSet (const
    LinkStringSet set)
  • myFirst(new Node("header",set.clone())),
  • mySize(set.size())
  • // uses header node
  • // initializer list made deep copy
  • const LinkStringSet
  • LinkStringSetoperator (const LinkStringSet
    set)
  • if (set ! this)
  • reclaimNodes(myFirst-gtnext)
  • myFirst-gtnext set.clone()
  • mySize set.size()
  • return this
  • LinkStringSetNode LinkStringSetclone()
    const

Linkstringset.cpp
19
Linksetdemo.cpp
  • int main()
  • LinkStringSet a,b
  • a.insert("apple")
  • a.insert("cherry")
  • cout ltlt "a " Print(a) //cherry apple 2
  • b a
  • cout ltlt "b " Print(b) //cherry apple 2
  • a.clear()
  • cout ltlt "a " Print(a) // 0
  • cout ltlt "b " Print(b) //cherry apple 2 -
  • //as intended with , provided by deepcopy in
    linkstringset.cpp
  • return 0
  • Complete project is in linkstringset.zip you
    should play with it.

20
Tapestry Chp. 9.4clockt.h and clockt.cpp
  • We will now look at the Tapestrys clock class
    for
  • more operator overloading
  • class design
  • How to design a clocktime class?
  • to represent a clock-time object 195900

21
ClockTime Class
  • class ClockTime
  • public
  • ClockTime()
  • ClockTime(int secs, int mins, int hours)
  • int Hours() const //
    returns hours
  • int Minutes() const //
    returns minutes
  • int Seconds() const //
    returns seconds
  • string tostring() const //
    converts to string
  • bool Equals(const ClockTime ct) const
    // true if ct
  • bool Less (const ClockTime ct) const
    // true if lt ct
  • const ClockTime operator (const
    ClockTime ct)
  • private
  • void Normalize() //normalized form
    should be like 0-24hr0-60min0-60sec
  • int mySeconds // constrained 0-59
  • int myMinutes // constrained
    0-59

22
  • ClockTimeClockTime (int secs, int mins, int
    hours)
  • mySeconds(secs), myMinutes(mins),
    myHours(hours)
  • // postcondition all data fields initialized
  • Normalize()
  • void ClockTimeNormalize()
  • myMinutes ...
  • mySeconds ...
  • myHours ...
  • myMinutes ...

23
  • ClockTimeClockTime (int secs, int mins, int
    hours)
  • mySeconds(secs), myMinutes(mins),
    myHours(hours)
  • // postcondition all data fields initialized
  • Normalize()
  • void ClockTimeNormalize()
  • myMinutes mySeconds/60 // overflow
    from secs to myMinutes
  • mySeconds 60 // now
    between 0 and 59
  • myHours myMinutes/60 // overflow
    from myMinutes to myHours
  • myMinutes 60 // now
    between 0 and 59

24
Helper Functions of the clocktime class
  • These will be used in operator overloading. They
    implement the straightforward meaning (make sure
    you understand)
  • bool ClockTimeEquals (const ClockTime c)
    const //usage c1.Equals(c2)
  • // postcondition returns true iff this objects
    time c
  • return ( Hours() c.Hours()
  • Minutes() c.Minutes()
  • Seconds() c.Seconds() )
  • Alternative
  • bool ClockTimeEquals (const ClockTime c)
    const
  • // postcondition returns true iff this objects
    time c
  • return ( myHours c.myHours
  • myMinutes c.myMinutes
  • mySeconds c.mySeconds )

25
Helper Functions of the clocktime class
  • These will be used in operator overloading. They
    implement the straightforward meaning (make sure
    you understand)
  • bool ClockTimeLess (const ClockTime c) const
    //usage c1.Less(c2)
  • // postcondition returns true iff lt c
  • return ( Hours() lt c.Hours() )
  • ( ( Hours() c.Hours() )
  • ( ( Minutes() lt
    c.Minutes() )
  • ( ( Minutes()
    c.Minutes() ) ( Seconds() lt c.Seconds() ) )
  • )
  • )

26
Overloading Operators
  • Now lets overload the operator gt. First notice
    that we should be able to use the gt operator
    with clocktimes in 3 ways
  • clocktime c1, c2
  • int n 1
  • if ( c1 gt c2) or
  • if ( c1 gt 1) (let this mean c1 is more than
    or equal to 1 hr)
  • or
  • if ( 1 gt c1) ...

27
Overloading complete case for gt
  • Now lets overload the operator gt.
  • First notice that we should be able to use the gt
    operator with clocktimes in 3 ways
  • clocktime c1, c2
  • int n 1
  • if ( c1 gt c2) //calls c1.operatorgt(c2) b
    ool Clocktimeoperatorgt(const clocktime rhs)
  • return ! ( Less(rhs) ) //uses the helper
    function Less() of c1.
  • if ( c1 gt 1) //calls c1.operatorgt(1) let
    this mean is the time more than 1 hr
  • bool Clocktimeoperatorgt(const int rhs)
  • return ( Hours() gt rhs )
  • //uses the accessor function Hours() of c1.
  • //alternative return ( myHours gt rhs )
  • //since the member functions can access
    private data
  • if ( 1 gt c1) //cannot call
    1.operatorgt(c1) since 1 is a constant, so this
    version of the operatorgt must be a free
    function

28
Overloading complete case for gt
  • if ( c1 gt c2) //calls c1.operatorgt(c2) b
    ool Clocktimeoperatorgt(const clocktime rhs)
  • return ! ( Less(rhs) ) //uses the helper
    function Less() of c1.
  • if ( c1 gt 1) //calls c1.operatorgt(1) let
    this mean is the time more than 1 hr
  • bool Clocktimeoperatorgt(const int rhs)
  • return ( Hours() gt rhs )
  • //uses the accessor function Hours() of c1.
  • //alternative return ( myHours gt rhs )
  • //since the member functions can access
    private data
  • if ( 1 gt c1) //cannot call
    1.operatorgt(c1) since 1 is a constant, so this
    version of the operatorgt must be a free
    function
  • bool operatorgt(const int lhs, const
    clocktime rhs)
  • return ( lhs gt rhs.Hours() )

29
Overloading complete case for gt
  • This function appears as a free function (outside
    class definition)
  • bool operatorgt(const int lhs, const clocktime
    rhs)
  • return ( lhs gt rhs.Hours() )
  • If the clocktime class did not provide an
    accessor function Hours(), we would have a
    problem, since free functions cannot access
    private data (myHours)
  • Alternatively, we could make the free function a
    friend function of the clocktime class
  • Add friend bool operatorgt(const int lhs,
    const clocktime rhs) in the class declaration
    (before the keyword public).

30
Operator
  • Usage Interpreted as
  • c1 ct c1.operator(ct)
  • const ClockTime ClockTimeoperator (const
    ClockTime ct)
  • // postcondition add ct, return result
    (normalized for myMinutes, mySeconds)
  • mySeconds ct.mySeconds
  • myMinutes ct.myMinutes
  • myHours ct.myHours
  • Normalize()
  • return this

31
  • why operator returns this?
  • same arguments as for the assignment operator ()
  • in case someone uses clockt c1 (c2 c3)
    etc.
  • This is ugly (do not use statements like this),
    but in general one should design the same
    behavior as it exists for built-in types (it is
    legal to say this for ints etc)

32
Clocktime.cpp other overloaded operators
  • In clocktime cpp, only some forms of the
    overloaded operators are provided (apparently
    they did not see a good use comparing clocktime
    objects to constants etc.) and most are declared
    as free functions
  • ostream operator ltlt (ostream os, const
    ClockTime ct)
  • ClockTime operator (const ClockTime lhs,
    const ClockTime rhs)
  • bool operator (const ClockTime lhs, const
    ClockTime rhs)
  • bool operator ! (const ClockTime lhs, const
    ClockTime rhs)
  • bool operator lt (const ClockTime lhs, const
    ClockTime rhs)
  • bool operator gt (const ClockTime lhs, const
    ClockTime rhs)
  • bool operator lt (const ClockTime lhs, const
    ClockTime rhs)
  • bool operator gt (const ClockTime lhs, const
    ClockTime rhs)
  • However, most of these particular functions
    can/should be member functions
  • (except for the ltlt operator which has to be a
    free function)
  • since they have a left-hand-side which is a
    clocktime object, they can be member functions
    (which is better)
  • But as shown in the previous slide, when we are
    writing versions of the overloaded operators
    which has constants on the left-hand-side, they
    have to be free functions using accessors, or be
    free friend functions, as shown before.

33
Operator
  • Usage Interpreted as
  • c c1 c2 c (operator(c1,c2))
  • The free function operator using the previously
    defined operator of the class
  • ClockTime operator (const ClockTime lhs, const
    ClockTime rhs)
  • // postcondition return lhs rhs (normalized
    for myMinutes, mySeconds)
  • .............................. //uses the
    previously defined copy constructor
  • .............................. //uses the
    previously defined operator
  • .............................

34
  • The free function operator using the previously
    defined operator of the class
  • ClockTime operator (const ClockTime lhs, const
    ClockTime rhs)
  • // postcondition return lhs rhs (normalized
    for myMinutes, mySeconds)
  • ClockTime result(lhs) //uses the previously
    defined copy constructor
  • result rhs //uses the previously
    defined operator
  • return result
  • why operator makes a copy first?
  • c a b should not change as value

35
Overloading I/O operators
  • ostream operator ltlt (ostream os, const
    ClockTime ct)
  • // postcondition inserts ct onto os, returns os
  • // format is hms
  • os ltlt ct.tostring()
  • return os
  • string ClockTimetostring() const
  • ostringstream os //to use a string as a
    stream
  • os.fill('0') //fill it with 0s
  • os ltlt Hours() ltlt "" ltlt setw(2) ltlt Minutes()
    ltlt ""
  • ltlt setw(2) ltlt Seconds() 10959
  • return os.str()

36
Overloading I/O operators
  • ostream operator ltlt (ostream os, const
    ClockTime ct)
  • // postcondition inserts ct onto os, returns
    os
  • // format is hms
  • os ltlt ct.tostring()
  • return os
  • operator ltlt cannot be a member function (in
    general)
  • cout ltlt c1 // ltlt is also a member function of
    cout //which would cause a source of
    conflict/confusion
  • ostream (output streams) has to be passed as
    reference
  • Since the ostream is modified when you put
    something on the string
  • operator ltlt must return the os
  • in case we use cout ltlt c1 ltlt c2 since cout is
    left associative, the result of
  • cout ltlt c1 must be the os.

37
Overloading I/O operators
This is an alternative not using the tostring()
but using accessor functions directly instead
(it has to, because free functions cannot access
private data of a class). But the tostring()
version is better.
  • ostream operator ltlt (ostream os, const
    ClockTime ct)
  • // postcondition inserts ct onto os, returns os
  • ostringstream ostr
  • ostr.fill('0')
  • ostr ltlt ct.Hours() ltlt "" ltlt setw(2) ltlt
    ct.Minutes() ltlt ""
  • ltlt setw(2) ltlt ct.Seconds()
  • os ltlt ostr.str()
  • return os

string ClockTimetostring() const
ostringstream os //to use a string as a stream
os.fill('0') //fill it with 0s os ltlt
Hours() ltlt "" ltlt setw(2) ltlt Minutes() ltlt ""
ltlt setw(2) ltlt Seconds() return
os.str()
38
Other overloaded operators
  • bool operator (const ClockTime lhs, const
    ClockTime rhs)
  • return lhs.Equals(rhs)
  • bool operator ! (const ClockTime lhs, const
    ClockTime rhs)
  • return ! (lhs rhs)
  • ...

39
Linkstringsetiterator.h
  • class LinkListIterator
  • public
  • LinkListIterator(const LinkList
    list) //constructor
  • myList(list), myCurrent(0)
  • void Init() //initialize the iterator
  • myCurrent myList.myFirst-gtnext
  • bool HasMore() const //more nodes on the
    list?
  • return myCurrent ! 0
  • string Current() const //return the info
    of the current node
  • return myCurrent-gtinfo
Write a Comment
User Comments (0)
About PowerShow.com