Storage Structures for Container Classes - PowerPoint PPT Presentation

1 / 51
About This Presentation
Title:

Storage Structures for Container Classes

Description:

is created and destroyed (dynamically) during execution, which can save a lot of ... Adidas. Nike. NULL. 2. 29. head. NULL. 0. length. Linked string sneakerList; ... – PowerPoint PPT presentation

Number of Views:83
Avg rating:3.0/5.0
Slides: 52
Provided by: jian9
Category:

less

Transcript and Presenter's Notes

Title: Storage Structures for Container Classes


1
Chapter 2
  • Storage Structures for Container Classes

2
Outline
  • Dynamic Variables and Pointers
  • Container Classes
  • linked structures
  • class Linked
  • Iterator
  • Standard Template Library
  • Function Templates
  • Class Templates

3
A Dynamic Variable
  • is created and destroyed (dynamically) during
    execution, which can save a lot of space in
    memory.
  • is stored on the Heap, a large area of memory
  • is never accessed directly.
  • is accessed through pointer variables.
  • Memory management
  • Stack vs. Heap
  • int b // b is created on stack, also called
    static allocation, i.e., before the execution of
    the program
  • variable (like b) created on stack is destroyed
    when the function in which it was declared
    returns, e.g. return 0 for variables declared in
    main()

4
A Pointer Variable
  • Contains the address of a variable (usually, a
    dynamic variable).
  • A pointer type is a type followed by an asterisk
  • int iPtr // preferred way
  • !!! NOTE This is equivalent to
  • int iPtr
  • or
  • int iPtr
  • Here, iPtr is a pointer variable (stored on the
    stack), specifically, a pointer to an
    int type variable.

stack
iPtr
pointer variable
5
To Create A Dynamic Variable
  • The new operator is used
  • iPtr new int
  • The execution of this statement creates a
    dynamic variable (on heap) pointed to by pointer
    variable iPtr (on stack) which holds the address
    (e.g., 00101011) of the dynamic variable.

stack
heap
iPtr
?
00101011
00101011
pointer variable
dynamic variable
6
To Access The Dynamic Variable
  • We dereference the pointer variable.
  • The dereference operator, , is placed in front
    of the pointer variable iPtr
  • The dynamic variable can now be treated as an
    ordinary int variable (on the heap).
  • For example,iPtr 5 // note to left
    of iPtr

stack
heap
iPtr
5
pointer variable
dynamic variable
7
To Destroy A Dynamic Variable
  • The delete operator is used delete iPtr
  • This deallocates the space for the dynamic
    variable pointed to by pointer variable iPtr.
  • That space (on heap) can now be allocated for
    another dynamic variable.
  • !!! NOTE the pointer variable iPtr still exists
    (on stack), which will be deleted (automatically)
    when the function in which it was declared
    returns

stack
iPtr
GO OVER NOTES ON POINTERS
pointer variable
8
Example 1 int type pointer
int p, q // asterisk needed for each
pointer variable p new int q new int p
55 q 0 cout ltlt p ltlt ltlt q ltlt endl q
p cout ltlt p ltlt ltlt q ltlt endl delete
p // delete the dynamic variable pointed to by
p delete q // delete the dynamic variable
pointed to by q // p and q are still alive
55 0
55 55
9
Example 2 string type pointer
string sPtr sPtr new string cin gtgt
sPtr while (sPtr ! "") if
((sPtr).length() lt 6) cout ltlt sPtr ltlt " is
a small word." ltlt endl else cout ltlt sPtr
ltlt " is not a small word." ltlt endl cin gtgt
sPtr // while delete sPtr
10
Example 2 string type pointer
  • In the expression (sPtr).length() lt
    6parentheses around sPtr are needed The
    member-selection operator (the dot) has higher
    precedence
  • Alternative notation the
    dereference-and-select operator is -gt
  • sPtr-gtlength() lt 6
  • This is equivalent to
  • (sPtr).length() lt 6

11
Example 3 class type pointer
int main() // regular object created on
stack Employee emp1 emp1.setName(Tom)
// create pointer variables (on stack)
Employee emp2, emp3 // use default
constructor to create // dynamic Employee
object (on heap) emp2 new Employee //
member-selection operator (the dot)
(emp2).setName(Jerry) (emp2).setSalary(900
) // use custom constructor emp3 new
Employee(Mary) // Alternatively, we can
use // dereference-and-select operator -gt
emp3-gtsetSalary(1000) emp3-gtprint() //
delete dynamic objects, delete emp2, emp3
// pointer variables still alive return 0
class Employee public Employee () name
NULL salary 0.0 Employee (string
inName) name inName salary 0.0
void setName(string inName) name inName
string getName() return name void
setSalary(double inSl) salary inSl
double getSalary() return salary
void print() cout ltlt Name ltlt name
ltlt Salary ltlt salary ltlt endl
protected string name double salary
12
Pointer Fields
// student.h class Student public
Student() void setID(int inID) int
getID() Student() // destructor
private int id // declare pointer
// student.cpp include student.h StudentStud
ent() id new int // create dynamic
variable void StudentsetID(int inID) id
inID // use dynamic variable int
StudentgetID() return id StudentStuden
t() delete id // delete dynamic variable
int main() Student stu
stu.setID(1234) cout ltlt The ID is ltlt
stu.getID() return 0
13
Dynamic Arrays
  • GO OVER NOTES ON ARRAYS
  • Dynamic Arrays
  • int dynArrdynArr can be a pointer to either a
    single int or to an array of integers.
  • dynArr new int 5
  • creates an array of 5 (dynamic) integer type
    variables and stores in dynArr a pointer to the
    zero-th element in this array.

dynArr
14
The Index Operator, operator
  • Random-access any item in an array can be
    accessed or modified immediately, given the index
    of the item
  • for (int i 0 i lt 5 i)
  • cin gtgt dynArr i
  • Is used to reference the individual items
  • dynArr 0 3This is equivalent
    to dynArr 3
  • In general, for any array a and non-negative
    integer i,
  • ai is equivalent to (a i), e.g.,
  • dynArr1 8 is the same as (dynArr 1) 8

15
Dynamic Allocation
  • A regular arrays capacity is fixed once created
  • But for a dynamic array, we can specify the size
    as follows
  • int capacitycin gtgt capacityint dynArr
    new int capacity
  • Note that the capacity need not be known until
    run time.

16
Destroy A Dynamic Array
  • To Destroy A Dynamic Array the pointer point to
    (NOT the pointer itself!!!)
  • To deallocate the space for an dynamic array,
    use an empty index
  • delete dynArr
  • Let pointer dynArr point to a new resized array
  • capacity 2 // double the
    capacity dynArr new int capacity

17
Container Classes
  • A container is an object that consists of a
    collection of items.
  • For example, an array is a container.
  • A container class is a class whose objects are
    containers.
  • There are two widely used kinds of structures for
    storing the items in a container object
  • An array and a linked structure.
  • In the first structure, one of the fields in the
    class is an array, and the items are stored in
    this array.
  • Advantage allows random-access of items.
  • Drawback large-scale movement of items for
    inserting, deleting, and resizing (due to fixed
    size).
  • There will be methods to handle movement of
    items, but even so, execution speed may be slow.

18
Container Classes
  • Another way to store a container is in a linked
    structure
  • each item has an associated link that is, a
    pointer to the next item in the container.

12
51
27
  • Linked Class
  • To give you a feel for a linked structure, we now
    design and implement a toy class, Linked.
  • We start with a users view
  • Instead of restricting the class to work with
    just one type of item, we will let the user
    select the item type when the user defines the
    container object.

19
Class Templates
  • To allow this, we will define a template, or
    mold, that will allow the definition, at
    compile-time, of a container class of some fixed
    type.
  • The container class is a template class, and the
    given type is a template argument.
  • template ltclass Tgtclass Linked
  • ...
  • T may be any type double, int, Employee, Student
    and so on.
  • For example, a user can defineLinkedltstringgt
    wordsLinkedltdoublegt salariesLinkedltEmployeegt
    employees

20
Review of Function Templates
CSCI 1010 notes
21
Why use function templates
CSCI 1010 notes
  • int Max (int a, int b)
  • if (a gt b)
  • return a
  • return b
  • How can we write it for any data type?
  • All we need to do is change int in 3 places
  • C lets us use int as an argument to a
    generic function that produces the code for
    different data types in actual functions
  • Using Cs template construct
  • Passing it int as an argument for those three
    places

22
How Do We Do That?
CSCI 1010 notes
  • By Using the C template Construct
  • Before any function we want to be generic,
    put template ltclass Tgt
  • T is the name of the parameter to the generic
    function
  • Write the function, replacing the desired data
    type with T (or whatever name you want)
  • template ltclass Tgt
  • T Max (T a, T b)
  • if (a gt b)
  • return a
  • return b

23
One More Detail
CSCI 1010 notes
  • We forgot about the function declaration
  • It has to be the same as the definitions header
  • So, it has to have that template ltclass Tgt, too
  • The declaration looks like this template ltclass
    Tgt T Max (T a, T b)
  • How does C do that?
  • Makes a text copy of the templated function
  • Substitutes the type argument in the function
    call into the type parameter in the function
    defn.
  • Then compiles the resulting code

Note no semicolon
24
CSCI 1010 notes
  • Contains
  • Declaration of templated function Max
  • main () function used to test templated function
    Max
  • Definition of function Max
  • Note in main () how Max is called
  • No differently than before
  • BUT it works with any data type
  • Even string
  • Whats the restriction on whether that Max will
    work?
  • Operator gt must be defined for the argument
    data type
  • For built-in types and library classes, thats a
    given
  • For classes you write yourself, you have to make
    sure of it
  • Exercise T Sum (T a, T b)

25
Methods in the Linked class
  • To construct an empty Linked object
  • To return the number of items currently stored in
    a Linked object
  • To insert an item at the front of a Linked object.
  • // Postcondition this Linked object is empty,
    that is,// it contains
    no items.Linked( )
  • // Postcondition the number of items in this
    Linked// object has been
    returned.long size( )
  • // Postcondition newItem has been inserted at
    the// front of this
    Linked object.void push_front (const T
    newItem)

26
struct node
item next
  • struct Node T item // T is the
    template parameter
  • Node next
  • The only fields in the Linked class are Node
    head // points to first node long length //
    number of items in the container
  • So head is the gateway to the entire container!

27
Default Constructor And The size Method
  • Linked( ) head NULL
  • length 0 // default constructor
  • long size( ) return length // method size

28
Example
  • Linkedltstringgt sneakerList
  • sneakerList.push_front (Nike)
  • sneakerList.push_front (Adidas)

item next item next
head
Adidas
Nike
NULL
length
2
29
Creating a Linked object (list)
Linkedltstringgt sneakerList
length
head
NULL
0
30
Inserting an item
sneakerList.push_front (Nike)
newHead
length
head
NULL
0
?
?
void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
31
Inserting an item
sneakerList.push_front (Nike)
newHead
length
head
NULL
0
?
Nike
void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
32
Inserting an item
sneakerList.push_front (Nike)
newHead
length
head
NULL
0
Nike
NULL
void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
33
Inserting an item
sneakerList.push_front (Nike)
newHead
length
head
1
Nike
NULL
  • // Postcondition A node with newItem has been
    inserted at the front of the Linked container.

void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
34
sneakerList.push_front (Adidas)
newHead
?
?
length
head
1
Nike
NULL
void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
35
sneakerList.push_front (Adidas)
newHead
?
Adidas
length
head
1
Nike
NULL
void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
36
sneakerList.push_front (Adidas)
newHead

Adidas
length
head
1
Nike
NULL
void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
37
sneakerList.push_front (Adidas)
newHead

Adidas
length
head
2
Nike
NULL
void push_front (const T newItem) Node
newHead new Node newHead -gt item
newItem newHead -gt next head head
newHead length
38
Deleting an Item
  • // Precondition this Linked container is
    not empty.// Postcondition the front item has
    been deleted from this Linked container
  • void pop_front() Node oldHead head
    head head -gt next delete oldHead //
    deallocates oldHead --length

39
Deleting an Item
sneakerList.pop_front( )
oldHead
length
head

2
Nike
NULL
Adidas
void pop_front() Node oldHead head
head head -gt next delete oldHead //
deallocates oldHead --length
40
Deleting an Item
sneakerList.pop_front( )
oldHead

length
Adidas
head
2
Nike
NULL
void pop_front() Node oldHead head
head head -gt next delete oldHead //
deallocates oldHead --length
41
Deleting an Item
sneakerList.pop_front( )
oldHead
?
length
head
1
Nike
NULL
void pop_front() Node oldHead head
head head -gt next delete oldHead //
deallocates oldHead --length
42
Destructor
  • // Postcondition This Linked object is
    empty, and the space occupied by //
    this Linked object has been
    deallocated.Linked() while (head !
    NULL) pop_front( )

43
Destructor
  • Destructor is automatically called when the
    object goes out-of-scope, that is, when the
    object is no longer accessible.
  • // function sample
  • void sample( ) Linkedltdoublegt
    weights
  • int main( ) sample( ) return 0
  • At the end of the execution of the function
    sample, the linked object weights is
    out-of-scope, so its destructor is automatically
    called.

44
Iterators
  • An iterator is an object that enables a user to
    loop through a container without violating the
    principle of data abstraction.
  • The Linked and Iterator classes together must
    provide a user with the ability to do at least
    the following
  • Start at the beginning of the container
  • Determine when no more loop iterations are
    possible, e.g., at the end
  • Advance to the next item in the container
  • Return the item where the iterator is now
    positioned.

45
The Linked Class
  • Provide the following two methods
  • // Postcondition An Iterator positioned at
    the front of this //
    Linked container has been returned.Iterator
    begin( )
  • // Postcondition An Iterator positioned just
    beyond the last item //
    in this Linked container has been
    returned.Iterator end( )

46
The Embedded Iterator Class
  • // Postcondition true has been returned if itr
    is equal to this Iterator.//
    Otherwise, false has been returned.bool
    operator (const Iterator itr) const
  • // Postcondition true has been returned if itr
    is not equal to this Iterator.
  • // Otherwise, false has been
    returned.bool operator! (const Iterator itr)
    const
  • // Precondition This Iterator is positioned at
    an item.// Postcondition The item this Iterator
    is positioned at has been returned.T
    operator( ) const
  • // Precondition This Iterator is positioned at
    an item.// Postcondition This Iterator has
    advanced to the next item unless this Iterator
    // was positioned at
    the back item in the Linked container before this
    call. // In that case,
    this Iterator is positioned just beyond the back
    item.Iterator operator (int) //
    post-increment operator

47
Example
  • Now a user can iterate through a Linked
    container
  • Linkedltstringgt sneakerList
  • sneakerList.push_front(Nike)
  • sneakerList.push_front(Adidas)
  • LinkedltstringgtIterator itr for (itr
    sneakerList.begin( ) itr ! sneakerList.end( )
    itr)
  • if (itr Adidas) cout ltlt
    Found Adidas! if ((itr).length() 4)
    cout ltlt Found a 4-letter words.

48
Design and Implementation of the Iterator Class
  • templateltclass Tgtclass Linked
    protected struct Node T
    item Node next
  • Node head long length
  • public class Iterator friend class
    LinkedltTgt
  • protected
  • public // class Iterator // class
    Linked

49
Construction
  • The Iterator class will have one field a pointer
    to the node where the Iterator object is
    positioned Node nodePtr
  • // Postcondition This Iterator has been
    initialized through newPtr.// constructor with
    pointer parameter Iterator (Node newPtr)
    nodePtr newPtr
  • This constructor is protected because users know
    nothing of Node. Therefore, to allow users to
    construct an Iterator object, there is a public
    default constructor
  • // Postcondition This Iterator has been
    constructed. Iterator( )

50
Definitions of ,!, AND
  • bool operator (const Iterator itr)
    const return nodePtr itr.nodePtr
  • bool operator! (const Iterator itr)
    const return nodePtr ! itr.nodePtr
  • T operator( ) const
  • return nodePtr -gt item

51
operator (int)
  • Here is one of several ways to define operator
    (int), the post-increment operator.
  • We construct a temporary iterator through
    nodePtr, advance nodePtr to point to the next
    node, and then return the temporary iterator.

Iterator operator (int) Iterator itr
(nodePtr) nodePtr nodePtr -gt next return
itr
  • Textbook Page 51 52 shows another way to define
    it.
Write a Comment
User Comments (0)
About PowerShow.com