CSci 152: Programming II Fall 2004 - PowerPoint PPT Presentation

1 / 42
About This Presentation
Title:

CSci 152: Programming II Fall 2004

Description:

p = new int; The first statement declares p to be a pointer variable ... Line 11: ~~~ Object one's data after destroying object two.p ~~~ x = 28. p = 2 4 6 8 10 ... – PowerPoint PPT presentation

Number of Views:19
Avg rating:3.0/5.0
Slides: 43
Provided by: DerekH71
Category:
Tags: csci | fall | programming | run | up

less

Transcript and Presenter's Notes

Title: CSci 152: Programming II Fall 2004


1
CSci 152 Programming IIFall 2004
  • Shallow vs. Deep Copy
  • Classes and Pointers

2
  • SHALLOW VERSUS DEEP COPY AND POINTERS
  • int p
  • p new int
  • The first statement declares p to be a pointer
    variable of the type int.
  • The second statement allocates memory of the type
    int, and the address of the allocated memory is
    stored in

3
  • p 87

int first int second first new int10
4
  • second first //Line

5
  • delete second

In a shallow copy, two or more pointers of the
same type point to the same memory that is, they
point to the same data.
6
  • second new int10
  • for(int j 0 j lt 10 j)
  • secondj firstj
  • In a deep copy, two or more pointers have their
    own data.

7
  • CLASSES AND POINTERS SOME PECULIARITIES
  • class pointerDataClass
  • public
  • ...
  • private
  • int x
  • int lenP
  • int p
  • pointerDataClass objectOne
  • pointerDataClass objectTwo

8
  • The Destructor
  • The object objectOne has a pointer data member p.
  • Suppose that during program execution the pointer
    p creates a dynamic array.
  • When objectOne goes out of scope, all data
    members of objectOne are destroyed.
  • However, p created a dynamic array, and dynamic
    memory must be deallocated using the operator
    delete.
  • If the pointer p does not use the delete operator
    to deallocate the dynamic array, the memory space
    of the dynamic array would stay marked as
    allocated, even though no one can access it.
  • How do we ensure that when p is destroyed, the
    dynamic memory created by p is also destroyed?

9
  • If a class has a destructor, the destructor
    automatically executes whenever a class object
    goes out of scope.
  • We can put the necessary code in the destructor
    to ensure that when objectOne goes out of scope,
    the memory created by the pointer p is
    deallocated.
  • pointerDataClasspointerDataClass()
  • delete p
  • class pointerDataClass
  • public
  • pointerDataClass()
  • ...
  • private
  • int x
  • int lenP
  • int p

10
  • The Assignment Operator

11
  • objectTwo objectOne
  • If objectTwo.p deallocates the memory space to
    which it points, objectOne.p would become
    invalid.

12
  • To avoid this shallow copying of data for classes
    with a pointer data member, C allows the
    programmer to extend the definition of the
    assignment operator.
  • This process is called overloading the assignment
    operator.
  • Chapter 16 explains how to accomplish this task
    by using operator overloading.
  • Once the assignment operator is properly
    overloaded, both the objects objectOne and
    objectTwo have their own data, as shown in Figure
    15-19.

13
  • The Copy Constructor
  • Consider the following statement
  • pointerDataClass objectThree(objectOne)
  • The object objectThree is being declared and is
    also being initialized by using the value of
    objectOne.
  • This initialization is called the default
    member-wise initialization.
  • The default member-wise initialization is due to
    the constructor, called the copy constructor
    (provided by the compiler.)
  • This default initialization would lead to a
    shallow copying of the data.

14
  • void destroyList(pointerDataClass paramObject)
  • destroyList(objectOne)

15
  • If a class has pointer data members
  • During object declaration, the initialization of
    one object using the value of another object
    would lead to shallow copying of data if the
    default member-wise copying of data is allowed.
  • If, as a parameter, an object is passed by value
    and the default member-wise copying of data is
    allowed, it would lead to shallow copying of
    data.
  • In both cases, to force each object to have its
    own copy of the data, we must override the
    definition of the copy constructor provided by
    the compiler.
  • This is usually done by putting a statement that
    includes the copy constructor in the definition
    of the class, and then writing the definition of
    the copy constructor.
  • For the class pointerDataClass, we can overcome
    this shallow copying of data problem by including
    the copy constructor in the class
    pointerDataClass.

16
  • The copy constructor automatically executes in
    two situations (as described in the previous
    list)
  • When an object is declared and initialized by
    using the value of another object
  • When, as a parameter, an object is passed by
    value
  • Once the copy constructor is properly defined for
    the class pointerDataClass, both objectOne.p and
    objectThree.p will have their own copies of the
    data. Similarly, objectOne.p and paramObject.p
    will have their own copies of the data.

17
  • Example 15-5
  • class pointerDataClass
  • public
  • void print() const
  • void setData()
  • void destroyP()
  • pointerDataClass(int sizeP 10)
  • pointerDataClass()
  • pointerDataClass (const pointerDataClass
    otherObject)
  • //the copy constructor
  • private
  • int x
  • int lenP
  • int p //pointer to an int array

18
  • void pointerDataClassprint() const
  • coutltlt"x "ltltxltltendl
  • coutltlt"p "
  • for(int i 0 i lt lenP i)
  • coutltltpiltlt" "
  • coutltltendl
  • void pointerDataClasssetData()
  • coutltlt"Enter an integer for x "
  • cingtgtx
  • coutltltendl
  • coutltlt"Enter "ltltlenPltlt" numbers "

19
  • void pointerDataClassdestroyP()
  • lenP 0
  • delete p
  • p NULL
  • pointerDataClasspointerDataClass(int sizeP)
  • x 0
  • if(sizeP lt 0)
  • coutltlt"Array size must be positive"ltltendl
  • coutltlt"Creating an array of size 10"ltltendl
  • lenP 10
  • else

20
  • pointerDataClasspointerDataClass()
  • delete p
  • //copy constructor
  • pointerDataClasspointerDataClass
  • (const pointerDataClass
    otherObject)
  • x otherObject.x
  • lenP otherObject.lenP
  • p new intlenP
  • for(int i 0 i lt lenP i)
  • pi otherObject.pi

21
  • include ltiostreamgt
  • include "ptrDataClass.h"
  • using namespace std
  • void testCopyConst(pointerDataClass temp)
  • int main()
  • pointerDataClass one(5) //Line 1
  • one.setData() //Line 2
  • coutltlt"Line 3 Object one's data"ltltendl
    //Line 3
  • one.print() //Line 4
  • coutltlt"Line 5______________________________"
  • ltlt"______________"ltltendl //Line 5
  • pointerDataClass two(one) //Line 6

22
  • one.print() //Line 12
  • coutltlt"Line 13_______________________________"
  • ltlt"_____________"ltltendl //Line 13
  • coutltlt"Line 14 Calling the function
    testCopyConst"
  • ltltendl //Line 14
  • testCopyConst(one) //Line 15
  • coutltlt"Line 16_______________________________"
  • ltlt"_____________"ltltendl //Line 16
  • coutltlt"Line 17 After a call to the function "
  • ltlt"testCopyConst, object one
    is"ltltendl //Line 17
  • one.print() //Line 18
  • return 0 //Line 19

23
  • void testCopyConst(pointerDataClass temp)
  • coutltlt"Line 20 Inside function "
  • ltlt"testCopyConst "ltltendl //Line 20
  • coutltlt"Line 21 Object temp data"ltltendl //Line
    21
  • temp.print() //Line 22
  • temp.setData() //Line 23
  • coutltlt"Line 24 After changing the object "
  • ltlt"temp, its data is "ltltendl //Line 24
  • temp.print() //Line 25
  • coutltlt"Line 26 Exiting function "
  • ltlt"testCopyConst "ltltendl //Line 26

24
  • Sample Run In this sample run, the user input is
    in red.
  • Enter an integer for x 28
  • Enter 5 numbers 2 4 6 8 10
  • Line 3 Object one's data
  • x 28
  • p 2 4 6 8 10
  • Line 5___________________________________________
    _
  • Line 7 Object two's data
  • x 28
  • p 2 4 6 8 10
  • Line 9___________________________________________
    _
  • Line 11 Object one's data after destroying
    object two.p
  • x 28
  • p 2 4 6 8 10
  • Line 13__________________________________________
    __
  • Line 14 Calling the function testCopyConst

25
  • Enter an integer for x 65
  • Enter 5 numbers 1 3 5 7 9
  • Line 24 After changing the object temp, its data
    is
  • x 65
  • p 1 3 5 7 9
  • Line 26 Exiting function testCopyConst
  • Line 16__________________________________________
    __
  • Line 17 After a call to the function
    testCopyConst, object one is
  • x 28
  • p 2 4 6 8 10

26
  • INHERITANCE, POINTERS, AND VIRTUAL FUNCTIONS
  • C allows the user to pass an object of a
    derived class to a formal parameter of the base
    class type.
  • class baseClass
  • public
  • void print()
  • baseClass(int u 0)
  • private
  • int x
  • class derivedClass public baseClass
  • public
  • void print()
  • derivedClass(int u 0, int v 0)

27
  • void baseClassprint()
  • coutltlt"In baseClass x "ltltxltltendl
  • baseClassbaseClass(int u)
  • x u
  • void derivedClassprint()
  • coutltlt"In derivedClass "
  • baseClassprint()
  • coutltlt"In derivedClass a "ltltaltltendl
  • derivedClassderivedClass(int u, int v)
  • baseClass(u)

28
  • void callPrint(baseClass p)
  • p.print()
  • int main()
  • baseClass one(5) //Line 1
  • derivedClass two(3, 15) //Line 2
  • one.print() //Line 3
  • two.print() //Line 4
  • coutltlt" Calling the function callPrint
    "
  • ltltendl //Line 5
  • callPrint(one) //Line 6
  • callPrint(two) //Line 7
  • return 0

29
  • Output
  • In baseClass x 5
  • In derivedClass In baseClass x 3
  • In derivedClass a 15
  • Calling the function callPrint
  • In baseClass x 5
  • In baseClass x 3

30
  • In compile-time binding, the necessary code to
    call a specific function is generated by the
    compiler.
  • Compile-time binding is also known as static
    binding.
  • For the statement in Line 7, the actual parameter
    is of the type derivedClass.
  • When the body of the function two executes,
    logically the print function of object two should
    execute, which is not the case.
  • C corrects this problem by providing the
    mechanism of virtual functions.
  • The binding of virtual functions occurs at
    program execution time, not at compile time.
  • This kind of binding is called run-time binding.
  • In run-time binding, the compiler does not
    generate code to call a specific function
    instead, it generates enough information to
    enable the run-time system to generate the
    specific code for the appropriate function call.
  • Run-time binding is also known as dynamic binding.

31
  • class baseClass
  • public
  • virtual void print() //virtual function
  • baseClass(int u 0)
  • private
  • int x
  • class derivedClass public baseClass
  • public
  • void print()
  • derivedClass(int u 0, int v 0)
  • private
  • int a

32
  • If we execute the previous program with these
    modifications, the output is as follows.
  • Output
  • In baseClass x 5
  • In derivedClass In baseClass x 3
  • In derivedClass a 15
  • Calling the function callPrint
  • In baseClass x 5
  • In derivedClass In baseClass x 3
  • In derivedClass a 15

33
  • //Chapter 15 Virtual Functions
  • include ltiostreamgt
  • include "classExtTestVirtual.h"
  • using namespace std
  • void callPrint(baseClass p)
  • int main()
  • baseClass q //Line 1
  • derivedClass r //Line 2
  • q new baseClass(5) //Line 3
  • r new derivedClass(3,15) //Line 4
  • q-gtprint() //Line 5

34
  • void callPrint(baseClass p)
  • p-gtprint()
  • Output
  • In baseClass x 5
  • In derivedClass In baseClass x 3
  • In derivedClass a 15
  • Calling the function callPrint
  • In baseClass x 5
  • In derivedClass In baseClass x 3
  • In derivedClass a 15

35
  • //Chapter 15 Virtual Functions and value
    parameters
  • include ltiostreamgt
  • include "classExtTestVirtual.h"
  • using namespace std
  • void callPrint(baseClass p)
  • int main()
  • baseClass one(5) //Line 1
  • derivedClass two(3, 15) //Line 2
  • one.print() //Line 3
  • two.print() //Line 4
  • coutltlt" Calling the function callPrint
    "

36
  • void callPrint(baseClass p) //p is a value
    parameter
  • p.print()
  • Output
  • In baseClass x 5
  • In derivedClass In baseClass x 3
  • In derivedClass a 15
  • Calling the function callPrint
  • In baseClass x 5
  • In baseClass x 3

37
  • THE ADDRESS OF OPERATOR AND CLASSES
  • The address of operator is also used to create
    aliases to an object.
  • Consider the following statements
  • int x
  • int y x
  • Both x and y refer to the same memory location.
  • y is like a constant pointer variable.
  • The statement
  • y 25
  • sets the value of y and hence of x to 25.
    Similarly the statement
  • x 2 x 30
  • updates the value of x and hence of y.

38
  • The address of operator, , can also be used to
    return the address of private data members of a
    class. However, if we are not careful this can
    result in serious errors in the program.
  • //header file testadd.h
  • ifndef H_testAdd
  • define H_testAdd
  • class testAddress
  • public
  • void setX(int)
  • void printX() const
  • int addressOfX() //this function returns
    the
  • //address of the private data
    member
  • private
  • int x
  • endif

39
  • //Implementation file testAdd.cpp
  • include ltiostreamgt
  • include "testAdd.h"
  • using namespace std
  • void testAddresssetX(int inX)
  • x inX
  • void testAddressprintX() const
  • coutltltx
  • int testAddressaddressOfX()
  • return x

40
  • //Test program
  • include ltiostreamgt
  • include "testAdd.h"
  • using namespace std
  • int main()
  • testAddress a
  • int y a.addressOfX()
  • a.setX(50)
  • coutltlt"x in class testAddress "
  • a.printX()
  • coutltltendl
  • y 25
  • coutltlt"After y 25, x in class testAddress "
  • a.printX()
  • coutltltendl

41
  • ifndef H_testAdd
  • define H_testAdd
  • class testAddress
  • public
  • void setX(int)
  • void printX() const
  • const int addressOfX() //this function
    returns the
  • //address of the
    private data
  • //member
  • private
  • int x
  • endif
  • const int testAddressaddressOfX()
  • return x

42
  • The definition of the function addressOfX in the
    implementation file is
  • const int testAddressaddressOfX()
  • return x
  • The same program now will generate compile time
    error.
Write a Comment
User Comments (0)
About PowerShow.com