Sei sulla pagina 1di 15

2E3: Pointers and Classes

Dr. Ivana Dusparic


http://www.scss.tcd.ie/Ivana.Dusparic/2E3/

Pointers and Classes

How does have dynamically allocated data


stored in a data member affect the following:

Constructors
Desctructors
Copy constructors
Assignment operators =

Message Reminder

Design a class to:

Store a reminder, i.e. a message with an associated time


Allow the reminder to be printed out with the time.
Allow the message and the time to be retrieved
independently.

Approach:

Message string (array of characters)


We should be able to handle variable length strings
dynamically allocate storage for message
Need to store a time use Time class from earlier.
Member data: m_message, m_time
Member methods: constructors, print(), getTime(),
getMessage()

Reminder Class Interface


The message is not stored:
only a pointer to the message
Uses user defined
class Time

getTime() returns an
object of class Time

Reminder Class

Have to take extreme care when dealing with


pointers in classes:

m_message is a pointer

Who created the array originally?


Should we copy the array or just store the pointer when
constructing?
Answer depends on whether we know exactly when the
array will be deleted
Must ensure the Reminder class does not fail due to things
happening elsewhere

Reminder Constructor

One possibility:

Just copy the pointer

A copy is made of
the value of the pointer
Object assignment/copy
used to record time

Reminder Default Constructor

Create a blank string (i.e. 1 element = zero terminator)

initialise the time


object with 0

Finally set character to


zero, so string is null

Create space for just


1 character, and save
pointer in m_message

Reminder Constructor

Reminder Constructor

But what happens here:

Why does this happen?

Because Reminder only stores a pointer to the string

Reminder Constructor

Now the Reminder object


creates its own unique
copy of the string, and
no-one else has access
to this, because the pointer
m_message is private to
Reminder.

32-bits

Stack
0x04100
0x04104
0x04108
0x0410c
0x04110
0x04114
0x04118
0x0411c

0x20400
0x20404
0x20408
0x2040c
0x20410
0x20414
0x20418
0x2041c

H
o
e

?
H
?
o
?
e

l
T
r
e
0x04100
10
20
30
0x20400
????

????
0x20414
????
11
????
10
????
20
????
30
?
?
e
l
?
?
T
?
?
r
e

l
h
0
str
m_hour
m_minute
m_second
r1

m_message
m_length
m_hour
m_minute
m_second

Reminder

?
l
?
h
?
0

newly allocated
storage for message

Heap

32-bits

Stack
0x04100
0x04104
0x04108
0x0410c
0x04110
0x04114
0x04118
0x0411c

H
Y
o
e

0x20400
0x20404
0x20408
0x2040c
0x20410
H
o
e

l
T
r
e
0x04100
10
20
30
0x20400
????

0x20414
11
10
20
30
e
l
T
r
e

l
h
0
str
m_hour
m_minute
m_second
r1

m_message
m_length
m_hour
m_minute
m_second
l
h
0

Heap

Reminder Destructor

We must ensure we delete any memory we


allocate
space allocated for
message string by
Reminder constructor

So when func() terminates, the pointer to


the Reminder object is lost, but we havent
freed the memory for the message
MEMORY LEAK

Reminder Destructor

The destructor for the Reminder class should delete


the string pointed to by m_message

The object goes out of scope, and the destructor


called when either:

The function terminates (if the object is a local variable)


The object is deleted using delete operator (if the object
was dynamically allocated)
The program terminates

Object Copying Time Class

Object Copying Time Class

Object Copying Time Class

Just like variables, objects can be assigned or


copied (as long as types match):

This is an element by element copy of the object


In exactly the same way you can pass objects as
parameters or return objects from functions.

Object Copying Reminder Class

What happens here

We have dynamically allocated message

object copying

Object Copying Reminder Class

Object Copying Reminder Class

Element-wise copy by default

value of m_message copied


r1 and r2 both point to same text
i.e. r1.m_message == r2.m_message
also deletion happens twice the destructor is
called twice!!!

When copying objects need to copy whole


message rather than just pointer to it

How?

10

Object Copying

There are 2 ways to copy an object:

Implicit copy:
copy r2 into r3
create space for r3 then
initialise it with contents of r2

Explicit copy:

= operator causes a copy from


contents of r2 to r1

Object Copying

In parameter
passing, values are
copied silently
Return values also
implemented as a
copy of the object

11

Copy Constructor

A special constructor used to safely copy


objects of a given class

Also used to initialise an object with another


object of that class
It is a constructor with one parameter that is the
same type as the class and is called by reference.
Normally the parameter is const.

Copy Constructor

Copy constructors are used to implement


deep copies

A shallow copy copies only the values, a deep


copy copies any data referenced by those values
(e.g. data pointed to by a pointer), to guarantee
full independent copies are made.

12

Copy Constructor

Shallow Copy
r1

r2

m_message
m_length

h
e
l
l
l
o
0

m_time

m_message
m_length
m_time

Copy Constructor
Deep Copy
r1
m_message
m_length
m_time

r2
h
e
l
l
l
o
0

m_message
m_length
m_time

h
e
l
l
l
o
0

13

Copy Constructor

Assignment Operator

Now we need to redefine what happens


when we assign Reminder objects:

We need to redefine = for Reminder objects


Override the = operator!

14

Object Copying in Function Calls

r2 copied to r
r copied to return value

return value assigned to r1

The Big Three

Must define all if you define any of:

Copy constructor
= operator
Destructor

Defaults provided by the compiler:

Work fine for simple classes with members of native type


only (e.g. int, double, char).
Will not work in general when you have pointers, or any
resources allocated by class.
Once you define one of the Big Three you should provide
an implementation for them all.

15

Potrebbero piacerti anche