Professional Documents
Culture Documents
Week6 Classes
Week6 Classes
7
Pointers
Similarly, we could write:
cout << *ptr;
UseofpointersinC++.cpp
Pointers and Array types
Okay, let us move on.
Let us consider why we need to identify the type
of variable that a pointer points to, as in:
int *ptr;
One reason for doing this is so that later, once ptr
"points to“ something, if we write:
*ptr = 2;
Pointers and array types
The compiler will know how many bytes to copy
into that memory location pointed to by ptr.
If ptr was declared as pointing to an integer, 4
bytes would be copied.
Similarly for floats and doubles the appropriate
number will be copied.
More on pointers
But, defining the type that the pointer points to
permits a number of other interesting ways a
compiler can interpret code.
For example, consider a block in memory
consisting of ten integers in a row.
That is, 40 bytes of memory are set aside to hold
10 integers.
Pointers and Array types
Now, let us say we point our integer pointer ptr at the
first of these integers.
Furthermore lets say that integer is located at memory
location 100 (decimal). What happens when we write:
ptr + 1;
Because the compiler "knows" this is a pointer (i.e.
its value is an address) and that it points to an
integer (its current address, 100, is the address of
an integer)
Pointer and Array types
it adds 4 to ptr instead of 1, so the pointer "points to" the next
integer, at memory location 104.
Similarly, were the ptr declared as a pointer to a short, it would
add 2 to it instead of 1.
The same goes for other data types such as floats, doubles, or
even user defined data types such as structures (which we
discussed last week).
This is obviously not the same kind of "addition" that we
normally think of.
In C++ it is referred to as addition using "pointer arithmetic", a
term which we will come back to later.
Pointers
Similarly, since ptr++ is equivalent to
ptr + 1, incrementing a pointer using the unary ++
operator, increments the address it stores by the
amount sizeof(type) where "type" is the type of
the object pointed to. (e.g. 4 for an integer).
Pointers and Arrays
Since a block of 10 integers located contiguously
(along a line, or next to) in memory is, by
definition, an array of integers, this brings up an
interesting relationship between arrays and
pointers.
Consider the following:
int my_array[ ] = {1,23,17,4,-5,100};
Pointers and Arrays
public:
void setID (int n);
int getID ();
void putwage (double w);
double getwage();
};
The class
A class is a logical abstraction, but an object
has physical existence.
access-specifier can be:
public: Allow functions or data to be accessible to
other parts of the program.
private: May be accessed only by other members
of the class.
protected: Used when inheritance is involved;
discussed later.
New terms
class is the keyword that begins a class declaration
By default members of a class are private to it, so if
we do not use an interface (i.e. public, private or
protected) the data become private, in a struct they
default to public (this is the main difference between
the two)
The public keyword is used to declare the public
members of the class
Objects
An object is like a variable only more
complex - it holds structured data and
exhibits certain behaviour.
The data access can be restricted (or
encapsulated). //new buzz word
The terms object and class are analogous to
the concepts of variables and datatypes
Objects
Objects are instances of a class.
The term instantiated is synonymous with
objects and classes.
It simply means to create a variable of that
particular class
Classes.
Consider a Student class, which defines
objects that have the following three
properties (accessible data):
Registration number which is of type integer
Name of type string
Fees of type integer
The student class
We can create an instance of the Student
class using either of the following syntaxes:
Student st(1234, "Mary Smith", 2420);
Student st = Student(1234, "Mary Smith",
2420);
The default constructor
We can also use the default constructor (if there is one
defined for the class) as follows to create an instance of
Student that contains the default data:
Student st;
Note that Student st(); is not valid code.
It is possible to redefine the contents of an object using
an assignment statement.
For example, the following statement changes the
contents of the already-existing object:
st = Student(5678, "Bill Brown", 1320);
Encapsulation.
Not all the data stored in an object is accessible to
the outside world.
Access is defined by the object's member
functions which expose the data through the
object's interface.
For example the Student class could have
an accessor member function called get_number()
that defines access to the student's ID number as follows:
st.get_number(); // returns the ID number of the
//Student object st
More on encapsulation
reg_no = st.get_number();
//assigns the ID number to the variable //reg_no. i.e.
//places it in it
To access the properties and member functions of
an object, use the dot operator as shown above.
Objects can also have mutator member functions
that allow the properties to be modified.
For example, you could use the Student class's
set_name() function to change the name property of
a student:
Classes again
st.set_name("Betty Jones");
this would change the name of st from Bill
Brown to Betty Jones.
A closer look at Classes I
int main(void)
{ Date d1;
Date d2(30, 11);
d1.display();
d2.display();
d1.add_day();
d1.display();
} //see Date.cpp
The Queue class
//this class implements a queue
class Queue{
int q[100];
int sloc, rloc; //start location and rear location
public:
void init();
void qput(int i);
int qget();
};
Classes continued
So a class contains both private and public
members
So q, sloc and rloc are private, this means that
they can be accessed only by other members of
the queue class e.g. the functions of this class
and NOT by other parts of the program in which
this class has been written.
The functions are also referred to as methods
This is known as ENCAPSULATION.
Classes continued
Typically we place the functions in the public
interface and the data in the private interface,
but we can declare private functions if we so
wished.
The functions init(), qput() and qget() are
called member functions of the class, note
the parentheses to denote that they are
functions.
Classes continued
Keep in mind that an object forms a bond between the functions
and the data.
A member function has access to the private parts of the class of
which it is a member.
Thus init(), qput() and qget() have access to q, sloc and rloc.
Once a class is declared we can create objects (variables) of the
type class as follows:
Queue q1, q2
This will declare two objects q1 and q2 of type Queue
Declaration of classes
class class_name{
private: data and functions
public: public data and functions
} object_list;
//recall we can do this with structs i.e. the
//object list part
Coding the functions
void queue::qput(int i)
{
if (sloc==100){
cout << “Queue is full ” << endl;
return;
}
sloc++;
q[sloc] = i;
}
//this will put the value i at position q[sloc] in the //array of
integers
:: The scope resolution
operator
Note the use of the ::
This is known as the scope resolution operator,
which means that the function name to the right of
the two colons is in the scope of the class name to
the left of the colon
In short it means that the function (or method)
belongs to the class or the method is in the scope of
the class.
The :: operator again
The :: is called the scope resolution operator.
Essentially it tells the compiler that this version of qput
belongs to the queue class
Or put differently :: states that qput() is in Queue’s
scope
Member functions can only be invoked relative to an
object. To call a member function from part of your
program that is not part of the class one must use the
object name and the dot operator, as we did with
structs e.g.
Queue ob1,ob2;
ob1.init();
The dot operator continued
The invocation ob1.init() causes init() to
operate on ob1’s copy of the data.
Keep in mind that ob1 and ob2 are separate
objects.
Loose coupling
Classes are very self contained
There only interaction with other parts of a project is via its public interface
which can be strictly monitored
They are very independent to other parts of your program
They can therefore be developed and tested in isolation
They result in more robust code
They are easy to reuse/ adapt/extend/
They are ideal for team programming
For large project they are more productive
They are ideal for large programs
Constructors and Destructors
Constructors guarantee initialisation and are called
when an object is created
Usually we want to set up an object with certain
values for its data.
Special member function called a constructor will
“construct” or initialise any instance of our class
exactly how we want to.
The constructor is called at the time of object
instantiation! i.e. when we create an object of that
class.
Revised class declaration
class Time
{
public:
void setTime (int hours, int minutes, int seconds);
void print24hour();
void print12hour();
Time(int initHrs, int intMins, int initSecs) //constructor
Time (); // overloaded constructor
~Time(); //destructor
private:
int hour;
int minute;
int second;
};
Define constructor
Time::Time()
{
cout << “Setting the time” << endl;
hrs=0;
mins=0;
secs = 0;
}
//Note the constructor has the same name as the class itself
//constructors have NO RETURN TYPE not even void.
Purpose of constructor and
destructor
Look at display.cpp
Pointers to Objects
As you know you can access a structure directly, or
through a pointer. In like fashion you can access an
object either directly or by using a pointer
Recall that a pointer stores an address
To access an element of an object when using the
actual object itself use the dot operator. When using
the pointer we use the -> (dereferencing operator)
See example p_Example.cpp
Extending classes
Here we derive one class from another
The derived class is called the child class or
the subclass
The class derived from is called the
superclass or the parent class
If one imagines set theory the parent class is
a sub set of the child class
Inheritance is known as a “is a” relationship
Extending in OO programming
Analogy to set theory
Child class
Parent class
enum ZoneType {EST, CST, MST,
PST, EDT, CDT,MDT}
class ExtTime:public Time
{ instantiate object A of type
public: ExtTime
void Set(int hours, int
minutes, int seconds); int main() {
void print24hour(); ExtTime1 A;
void print12hour(); return 0;
ExtTime(int int Hours, int }
initMins, int initSecs,
ZoneType initZone);
ExtTime();
private:
ZoneType zone;
};
Further Ideas
C++ and other object oriented languages
take things further.
For example, Suppose we had a problem
modelling vehicles
We need an Abstract Data Type (ADT) for a
vehicle
Vehicle ADT
DATA:
Position
Speed
heading
Operation
Accelerate
Break
Turn
DisplayInfo
Suppose we want to model a
bus
A bus is a kind of vehicle
It would be good if we could make use of our
vehicle implementation and extend it to
include bus specific data members and
operations
Bus ADT
bus is a kind of vehicle plus
DATA:
nPassengers
Operations:
board passenger
alight passenger
DisplayInfo
This can be done using Inheritance