Transcript Slide 1

The Queue class
• //this class implements a Queue
class Queue{
int q[100];//an array of integers
int sloc, rloc; //start location and rear location
public:
void init();
void qput(int i);
int qget();
};
Classes continued
• So as we know 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 hiding 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 wanted to.
• 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 i.e. an object will have associated
with it both data and functions.
• 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 (i.e.
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//i added to the queue)
{
if (sloc==100){
cout << “Queue is full ” << endl;
return;
}
sloc++; //increment 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.
• Now look at queue*.cpp and discuss
A closer look at class member
access
• How to access class members is a cause
of considerable confusion for
programmers.
• So for this reason we will look at this in
more detail.
• Let us look at Myclass.cpp
Member function access
continued
• Lets look at setab().
• As it is a member function it can refer to a and
b directly without explicit reference to an object
i.e. without the dot operator
• Second note that a is private and b is public,
so b can be accessed by code outside
Myclass.
• So main() assigns a value of 20 to b
• reset() is a function of Myclass so has access
to members of the class without the use of dot
operator. In this case it calls setab()
Constructors and Destructors
• It is very common for some part of an object to
require initialisation before it can be used.
• Recall the Queue class previously, before the
Queue could be used the variables rloc and sloc
were set to zero. This was done using the
function init() //short for initialisation
• Automatic initialisation is done using the
constructor
• Lets look at the Queue2.cpp. (no constructor)
The use of a Constructor
Queue::Queue() //note no return type
{
rloc=0;
sloc=0;
cout << "Queue initialised " << endl;
}
Here the constructor writes to the screen Queue initialised, this is not
common practice.
An objects constructor is called at inception i.e. when the object is
created
The Destructor
• The complement to the constructor is the
destructor.
• In many cases an object will need to perform
some action or series of actions when it is
destroyed.
• Reasons for destructor: object may need to
deallocate memory that it had previously
allocated
The Destructor
• In C++ the destructor is the function that handles
deactivation.
• The destructor has the same name as the
constructor and thus the class, but it is preceded
by the tilda ~.
• Like constructors they do not have a return type.
• The Queue class does not require a destructor
but we will include one for illustration, see
Queue3.cpp
Parameterised Constructors
• A constructor can have parameters thus we can
have different signatures for the constructor.
• This allows you to give member variables values
at inception
• Lets look at Queue4.cpp
• Here we will see a constructor with more than
one signature, this is known as
POLYMORPHISM analogous to
OVERLOADING
Public and Private
• If you look closely at the previous definition of our
classes you may note one or two things
• class definition is similar to struct definition
– In fact C++ treats structs as classes where by default all
members are public
• class definition contains function prototypes
– the operations are bound tightly to the data
– class functions know about class data so you do not need
to pass class data to functions as arguments
The Private and public
interfaces
• class definition has a line with a label
public: this tells the compiler which parts
of the class are visible to other things
(clients) e.g. main() and other functions
• class members are by default are private.
• That is private members functions and
data which are hidden to all.
• private data and functions are only visible
to an object itself.
Class Data Manipulation
• The principle of Information Hiding is the
key for Object Oriented Programming.
• Access to data is tightly controlled via
public interface functions
– “Setters” to set data members
• SetHeight(3);
– “Getters” to obtain values of data members
• y = myTime.Write();
Here myTime is an object of type Time, say.
Built in operators
• int, char, float, double have built in operators
– + * / % etc
– classes do not have them
• like structs they have . (dot) and =
• You have to define and implement your own
operators (i.e. methods)
– It is possible but perhaps beyond this course to
redefine the built in operators to work on YOUR
class.
Specification an Implementation
Like Abstract Data Types (ADT’s) there are
two parts to classes
1. the specification – where one declares
the class
2. implement the function definitions i.e. to
code the functions. This is not crucial but
it is how it is discussed in many text
books.
Key Points so far
• Shows practical elements of object oriented
programming .
– Information hiding
• Via class syntax
•
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 independent of 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
• They ensure that objects created are properly
initialised
• They ensure that they are properly destroyed
– So they can sort out any garbage collection, for
example memory de-allocation.
• Once this is done properly then class can be used
more reliably.
Summary
• A class can be used to implement an ADT
• A class specifies members - the data and operations
(methods)
• Information hiding is a central idea to classes
• class members are private by default so if you forget
to include an interface they will be private by default
• Interface functions are explicitly labelled as public
• Classes provide automatic initialisation through
constructors
• Classes provide a place for garbage collection
through destructors.
• Creation of an object is achieved via a declaration
statement.
Structures versus Classes
• On the surface structures and classes are virtually
identical, so why introduce the class?
• Answer is rooted in C. A C struct is valid in C++. C has
no concept of private or public all members are public
in structs
• In C++ members are private by default as we are
trying to achieve encapsulation
• So to be compatible with C a new keyword was added.
• A struct is a class.
• Look at displaydatestruct.cpp
Arrays of objects
• We can create arrays of objects just as we
had arrays of structs previously
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 ->
//pronounced arrow link (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
{
public:
void Set(int hours, int
minutes, int seconds);
void print24hour();
void print12hour();
ExtTime(int int Hours, int
initMins, int initSecs,
ZoneType initZone);
ExtTime();
private:
ZoneType zone;
};
instantiate object A of type
ExtTime
int main() {
ExtTime A;
return 0;
}
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
– That is a Vehicle class, written by the user for
the user
Vehicle ADT
DATA:
position
speed
heading
Operations
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
• A class can inherit data and operations from
another class
• It can also redefine operations (this is called
polymorphism) so that they work with the new
class
– e.g DisplayInfo will need to be adapted to
display bus specific information as well as
vehicle information.
This can be done using Inheritance
• This process of inheritance further extends
the programmers ability to reuse and
extend code already written.
• These principles lie at the heart of OOP which are
– Information hiding
– Inheritance and polymorphism
Object Oriented Programming
• Identify what the goals are for a problem
• Identifying the objects that make up a
problem
• Identifying how the objects in a problem
interact with each other in order to satisfy
the goals
• Specifying ADTs that describe the objects
and operations needed for the problem
JAVA
• The second module at Oxford in JAVA takes these
concepts further
• JAVA is a “pure” object oriented language with a
distinct C++ flavoured Syntax
• It is pure in the sense you cannot program in Java
without classes.
• Everything in Java is a class
Inheritance in C++
Introduction: Modern object-oriented (OO) languages
provide three capabilities:
encapsulation
inheritance
polymorphism
which can improve the design, structure and reusability
of code.
Here, we will explore how the object-oriented (OO)
programming paradigm known as inheritance can be
used in C++.
All coded examples are available in lecture.
Is inheritance important to C++?
• Inheritance is what separates abstract
data type (ADT) programming from OO
programming.
• It is one the three paradigms that OO
programming has which we refer to when
discussing an OO programming language.
– Encapsulation
– Polymorphism
– Inheritance
When would I use inheritance?
• As a specification device.
• Human beings abstract things on two
dimensions: part-of and kind-of.
• A Ford Focus is-a-kind-of-a Car, and a Ford
Focus has-a Engine, Tires, etc.
• The part-of hierarchy has been a part of
software since the ADT style became relevant;
inheritance adds "the other" major dimension of
decomposition.
How do you express inheritance
in C++?
• By the : public syntax:
• class Car : public Vehicle {
public:
...//code for class Car
};
• Here the Car class inherits publicly from
the Vehicle class
Describing this
•
•
•
•
•
•
•
•
We state the above relationship in several ways:
Car is "a kind of a" Vehicle
Car is "derived from" Vehicle
Car is "a specialized" Vehicle
Car is a "subclass" of Vehicle
Car is a "derived class" of Vehicle
Vehicle is the "base class" of Car
Vehicle is the "superclass" of Car (this not as
common in the C++ community)
How do you express "private
inheritance"?
• When you use : private instead of : public. E.g.,
• class Food : private Bar {
public:
...
};
• Let us look at PublicProtected1.cpp,
PublicProtected2.cpp and PublicProtected3.cpp
• And explain
Inheritance types
Access of base
class member
Public inheritance
Protected
inheritance
Private inheritance
Public
Public members in
base class will be
public in derived
class
Public members of
the base class will
be protected in the
derived class
Public members in
the base class will
become private
members in the
derived class
Protected
Protected members
in base class will be
protected in derived
class
protected members
of the base class will
be protected in the
derived class
protected members
of the base class will
be private in the
derived class
private
Private members in
base class will be
hidden from the
derived class
Private members in
base class will be
hidden from the
derived class
Private members in
base class will be
hidden from the
derived class
What is the difference between
public, private, and protected?
• A member (either data member or member function)
declared in a private section of a class can only be
accessed by member functions and friends of that class
• A member (either data member or member function)
declared in a protected section of a class can only be
accessed by member functions and friends of that class,
and by member functions and friends of derived classes
• A member (either data member or member function)
declared in a public section of a class can be accessed
by anyone
Why can't my derived class access
private things from my base class?
• To protect you from future changes to the
base class.
• Derived classes do not get access to
private members of a base class.
• This effectively "seals off" the derived
class from any changes made to the
private members of the base class.
How can I protect derived classes from
breaking when I change the internal parts
of the base class?
•
•
•
•
A class has two distinct interfaces for two distinct sets of clients:
It has a public interface that serves unrelated classes
It has a protected interface that serves derived classes
Unless you expect all your derived classes to be built by your
own team, you should declare your base class's data members
as private and use protected access functions by which derived
classes will access the private data in the base class.
• This way the private data declarations can change, but the
derived class's code won't break (unless you change the
protected access functions).
More on Inheritance in C++
•
•
Introduction:
Modern object-oriented (OO) languages
provide three capabilities:
–
–
–
•
•
encapsulation
inheritance
polymorphism
which can improve the design, structure and
reusability of code.
Here, we will explore how the object-oriented
(OO) programming capability known as
inheritance can be used in C++.
Employee example:
•
•
Real-world entities, like employees, are
naturally described by both data and
functionality.
We will represent different types of
employees:
– a generic employee
– a manager
•
a supervisor
Inheritance
• For these employees, we will store data,
like their:
– name
– pay rate
• And...we will require some functionality,
like being able to:
– initialize the employee
– get the employee's fields (e.g., name)
• calculate the employee's pay
Employee class:
•
Object-oriented languages typically provide a natural way to treat
data and functionality as a single entity. In C++, we do so by
creating a class.
•
Here is a class definition for a generic Employee:
class Employee {
public:
Employee (string theName, float thePayRate);
string getName() ; //const;
float getPayRate(); // const;
float pay(float hoursWorked); // const;
protected:
string name;
float payRate;
};
Protected interface
• Note: For now, just think of the "protected"
keyword as being like "private".
Programming exercise 1
• Write a Time class with the following UML
Design Specification
Time
Hour int:
Second:int
Minute :int
Time()
setTime(int,int,int)
showTime_in24hr()
showTime_in12hr()
Write the so-called Driver
program
• Write the Time class with a program that
contains main so that we can run it
• For the Employee class on next slide look
at Inheritance1.cpp
Hierarchies
• Employee example: Real-world entities,
like employees, are naturally described by
both data and functionality.
• We will represent different types of
employees:
• a generic employee
• a manager
• a supervisor
Employee Hierarchy
• For these Employees, we will store data,
like their:
• name and pay rate
And...we will require some functionality, like
being able to:
• initialize the employee with data values
• get the employee's fields (e.g., name)
• calculate the employee's pay
• Employee class: Object-oriented languages
typically provide a natural way to treat data and
functionality as a single entity. In C++, we do so
by creating a class. Here is a class definition for
a generic Employee:
class Employee {
public:
Employee(string theName, float
thePayRate);
string getName();
float getPayRate();
float pay(float hoursWorked);
protected:
string name; float payRate;
};
What is protected?
• Note: For now, just think of the "protected"
access specifier as being like "private".
This class consists of:
A constructor to initialize fields of the class.
Methods to "get" the fields.
A method to calculate the employee's pay (given the number of hours worked).
Definitions for each of the methods follow:
Types of Inheritance
• access
If a member is declared in the
public interface
It may be used by any private or
protected function of the class or from
outside the class and invoked (or
called) from outside the class, for
example by the main() function
Type of inheritance
Protected
It may be used by
Any member function of the class or
a member of derived classes
Private
It may be used by
Only member functions of the class
Inheritance types
Access of base
class member
Public inheritance
Protected
inheritance
Private inheritance
Public
Public members in
base class will be
public in derived
class
Public members of
the base class will
be protected in the
derived class
Public members in
the base class will
become private
members in the
derived class
Protected
Protected members
in base class will be
protected in derived
class
protected members
of the base class will
be protected in the
derived class
protected members
of the base class will
be private in the
derived class
private
Private members in
base class will be
hidden from the
derived class
Private members in
base class will be
hidden from the
derived class
Private members in
base class will be
hidden from the
derived class
Employee::Employee(string theName, float thePayRate)
{
name = theName;
payRate = thePayRate;
}
string Employee::getName()
{
return name;
}
float Employee::getPayRate()
{
return payRate;
}
float Employee::pay(float hoursWorked) {
return hoursWorked * payRate; }
//class coded but no main in employee.cpp
Demo
• Look at inheritance2.cpp on vehicle, trucks
and the use of enumerated type
• Explain this code
• This program has no grandchild class
Declaring objects
• Note that the payRate is used as an hourly wage.
The class would be used something like this.
• Employee empl("John Burke", 25.0);
// Print out name and pay (based on 40
//hours work).
cout << "Name: " << empl.getName() << endl;
cout << "Pay: " << empl.pay(40.0) << endl;
Inheriting
• Manager class: In the real world, we do not
view everything as unique; we often view
something as being like something else but with
differences or additions.
• Managers are like regular employees; however,
there might be differences. For example, they
might be paid by a salary.
• Note: Employees paid by a salary (i.e., those
that are salaried) get a fixed amount of money
each pay period (e.g., week, 2 weeks, month)
regardless of how many hours they work.
The Manager class
• Our first attempt to write a class for a manager gives the following
class definition:
class Manager {
public:
Manager(string theName, float thePayRate, bool isSalaried);
string getName();
float getPayRate();
bool getSalaried() ;
float pay(float hoursWorked);
protected:
string name;
float payRate;
bool salaried; };
The manager class
• It mainly differs from Employee in that it
has an additional
• data field (salaried) and
• method (getSalaried()).
• The method definitions for class Manager
do not differ much from Employee either
Writing the methods/constructor
Manager::Manager(string theName, float
thePayRate, bool isSalaried)
{ //this is the constructor
name = theName;
payRate = thePayRate;
salaried = isSalaried;
}
string Manager::getName()
{ return name; }
float Manager::getPayRate()
{ return payRate; }
bool Manager::getSalaried()
{ return salaried; }
float Manager::pay(float hoursWorked)
{ if (salaried)
return payRate;
/* else */
return hoursWorked * payRate;
}
The manager continued
• They add very little new code to what was
written in Employee.
• Compared to Employee, in Manager
• The methods getName() and getPayRate() are
identical to those in Employee.
• Method getSalaried() is new.
• The constructor and pay() method work
differently.
• Nonetheless, they do some of the same work as
their counterparts in the Employee class
The methods
• Finally, the payRate has two possible uses in the
Manager class...
float Manager::pay(float hoursWorked)
{ if (salaried) return payRate;
else
return hoursWorked * payRate;
}
If the manager is salaried, payRate is the fixed rate for the pay period;
otherwise, it represents an hourly rate, just like it does for a regular
employee
Using methods
• Such a Manager can be used in a similar
manner to an Employee:
Manager mgr("Jan Kovacs", 1200.0, true);
// Print out name and pay (based on 40
//hours work).
cout << "Name:" << mgr.getName() << endl;
cout << "Pay: " << mgr.pay(40.0) << endl;
Inheritance
• Reuse: We have done unnecessary work to create
Manager, which is similar to (and really is a "kind of")
Employee.
• We can fix this using the OO concept of inheritance.
• If we let a manager inherit from an employee, then it will
get all the data and functionality of an employee.
• We can then add any new data and methods needed for
a manager and redefine any methods that differ for a
manager.
• Here, we show a new implementation of Manager that
inherits from Employee:
Manager inheriting
class Manager : public Employee
{
public:
Manager(string theName, float thePayRate, bool
isSalaried);
bool getSalaried();
float pay(float hoursWorked) ;
protected:
bool salaried;
};
Public inheritance
• The line:class Manager : public Employee
• causes Manager to inherit all the data and
methods of Employee.
• Note: Although other access specifiers
(besides "public") can be used with
inheritance, we will discuss public
inheritance here.
The manager continued
• The only things included in the class definition
are:
• a constructor,
• the new field salaried,
• a way to access salaried with the method
getSalaried(),
• and a declaration for pay() (which is redefined in
Manager).
• Like this new class definition, the method
definitions are also simplified:
Manager::Manager(string theName, float
thePayRate, bool isSalaried) :
Employee(theName, thePayRate)
{ salaried = isSalaried; }
bool Manager::getSalaried()
{ return salaried; }
float Manager::pay(float hoursWorked)
{ if (salaried) return payRate;
/* else */
return Employee::pay(hoursWorked);
}
Member initialization
• There are some things to note about these
method definitions... Member
initialization list
• For constructors that require arguments,
you must write a new constructor for each
class.
• Note: Classes do not explicitly inherit
constructors.
• For the Manager class, we needed a
constructor:
Manager::Manager(string theName, float
thePayRate, bool isSalaried) : //note the colon
Employee(theName, thePayRate)
{ salaried = isSalaried; }
that does some of the same work as the Employee
constructor.
To do so, we reused Employee's constructor. The
only way to pass values to Employee's
constructor in this context is via a member
initialization list.
Member initialization
• A member initialization list follows a
constructor's parameter list.
• It consists of a colon (:) and a commaseparated list of inherited class names
(and values to be passed to their
constructors).
• Note: The member initialization list can also be used to pass values
to constructors of data members. For example,
class SomeClass {
public:
SomeClass();
private: const int SIZE;
AnotherClass data;
};
SomeClass::SomeClass() : SIZE(10), data("foo") {
// more initialization code }
Without doing so, SIZE could not be initialized (because it is constant)
and data's default constructor (if it has one) would be used.
The protected access specifier
• The protected access specifier
• Methods of Manager have access to payRate
because it was declared in Employee as
"protected":
float Manager::pay(float hoursWorked)
{ if (salaried) return payRate;
// Yeah, I can use! ...
}
i.e., classes that inherit a "protected" field or
method can access them.
The protected interface
• For those using an object (versus those
defining a class), "protected" works like
the "private" access specifier:
• Manager mgr;
• mgr.payRate; // Doesn't work! i.e., the
//"protected" fields remain inaccessible just
//as they were in Employee:
Employee empl;
empl.payRate; // Doesn't work!
• Calling inherited methods
• The pay() method of Manager uses a
different calculation if the manager is
salaried. Otherwise, it makes the same
calculation as a regular Employee:
float Manager::pay(float hoursWorked)
{ if (salaried) return payRate;
/* else */
return Employee::pay(hoursWorked); }
More on methods
• We reused the pay() method of Employee to
define the pay() method of Manager. Note that
when we call Employee's pay() method:
• Employee::pay(hoursWorked);
we must explicitly specify the class from which it
comes (i.e., from which it was inherited).
Without doing so, we'd have an infinite recursive
call:
The Manager class
float Manager::pay(float hoursWorked)
{ ...
return pay(hoursWorked); // Calls
//Manager::pay()!
}
• This new Manager class can be used just
like our first attempt:
• This new Manager class can be used just like
our first attempt:
Manager mgr("Jan Kovacs", 1200.0, true); // Print
//out name and pay (based on 40 //hours work).
cout << "Name: " << mgr.getName() << endl;
cout << "Pay: " << mgr.pay(40.0) << endl;
Excitingly, it has methods from Employee, like
getName(), that we did not declare or define in
Manager...
Remember, it inherited all the data and methods
of an Employee! Thus, we have reused our
definition of an employee to simplify defining a
manager.
Class Hierarchy
• Class Hierarchy: Since we now have one class that
inherits from another, we have the beginnings of a class
hierarchy:
• Employee
•
|
• Manager
• We say that Employee is the base class and Manager is
a derived class of Employee.
• Note: Alternatively, we may call Employee the
superclass and Manager the subclass. If needed, this
hierarchy could be extended to include more classes
Inheritance
•
•
a)
Adding a Supervisor
To add another type of employee, such as a supervisor, a new
class can be created. Two choices of where to place a Supervisor
class in the hierarchy are:
Employee
|
Manager
|
Supervisor
b) Employee
/
\
Manager Supervisor
C++ Syntax
class derived_class_name: public Base_class_name
{
//features
}
Eg
class Manager:public Employee
{
public:
Manager(string name,float salary);
private:
string department;
};
Hierarchy
•
•
•
a) A supervisor is a kind of manager.
The Supervisor class directly inherits from
Manager and indirectly inherits from
Employee.
b) A supervisor is just a special kind of
employee.
Supervisor directly inherits from Employee.
Aside: We can say that Supervisor inherits
from Employee when there is either a direct or
indirect inheritance relationship. Which
hierarchy would we choose?
Classes again
class class-name {
Access-specifier: data and functions
access-specifier: data and functions accessspecifier: data and functions
} object-list;
The Person class
class Person {
private:
string name;
int height;
public:
string getName();
void setName(string);
int getHeight();
void setHeight(int y);
}; // write implementation of this class
Interfaces
• 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 this week.
#include <iostream>
using namespace std;
class myclass {
int a, b;
public:
friend int sum(myclass x);
void set_ab(int i, int j);
};
void myclass::set_ab (int i, int j)
{
a = i; b = j;
}
// Note: sum() is not a member function of any class.
int sum (myclass x)
{
//Because sum() is a friend of myclass, it
// can directly access a and b.
return x.a + x.b;
}
main()
{ myclass n;
n.set_ab (3, 4);
cout << sum(n);
return 0; }
Friends
• A friend function has access to all
private and protected (and public of
course) members of the class for which
it is a friend.
• See friend1.cpp example
//use of friend function to access private data //members of class
class Myclass{
private:
int a,b;
public:
Myclass(int i, int j){a=i; b=j;}
friend int sum(myclass x);
};
//note sum is not a member function of any class
int sum (Myclass x)
{return x.a+x.b;}
int main(){
Myclass n(3,4);
cout << sum(n) << "\n";
return 0;
}
Friends
• The friend function negates information
hiding
• This is the whole idea of OO programming
i.e. encapsulation
• We now have a way of destroying this
property
• For this reason many programmers are
not keen on the use of friend functions
Arrays of Objects
• We can create arrays of objects just as we can
create an array of integers or doubles
• See ArrayofObjects1.cpp
• See ArrayofObjects2.cpp //this initialises
//an array of
// objects
• See ArrayofObjects3.cpp //2D array of
//objects
Pointers to Objects
• Recall we access a structure directly or indirectly
using a pointer to that structure.
• In like fashion we can access an object either
directly or indirectly using pointers again
• To access an element of an object when using
the actual object we use the dot notation
• To access a specific element of an object using
the pointer we use -> (arrow link)
• See objectpointer1.cpp
Incrementing pointers
• As we know when a pointer is
incremented(or decremented) it is
increased (or decreased) in such as way
that it will always point to next element of
its base type
• See objectPointer2.cpp
More on friends
• So it is possible to allow a non-member
function of any class to access the private
members of a class by declaring it as a
friend of the class.
• To make a function a friend of a class you
include its prototype in the public section
of a class declaration and precede it with
the friend keyword
Demo
• See friend2.cpp and explain
#include <iostream>
using namespace std;
class Myclass {
int a, b;
public:
friend int sum(myclass x);
void set_ab(int i, int j);
};
void Myclass::set_ab (int i, int j) {
a = i; b = j;
} // Note: sum() is not a member function of any class.
int sum (Myclass x)
{//Because sum() is a friend of myclass, it can directly access a and b.
return x.a + x.b;
}
main() {
Myclass n;
n.set_ab (3, 4);
cout << sum(n);
return 0; }
Assigning objects
• If both objects are of the same type (i.e.
both objects are of the same class) then
one object may be assigned to another.
• The following program demonstrates this
• See objectassignment1.cpp
#include <iostream>
using namespace std;
class Myclass{
private:
int a,b;
public:
void setab(int i,int j){a=i;b=j;}
void showab();
};
void Myclass::showab(){
cout << "a is " << a << endl;
cout << "b is " << b << endl;
}
int main(){
Myclass ob1,ob2;
ob1.setab(10,20);
ob2.setab(0,0);
cout << "ob1 before assignment" << endl;
ob1.showab();
cout << endl;
cout << "ob2 before assignment" << endl;
ob2.showab();
cout << endl;
ob2=ob1;
cout << "ob1 after assignment" << endl;
ob1.showab();cout << endl;
cout << "ob2 after assignment" << endl;
ob2.showab();cout << endl;
return 0;
}
Passing objects to functions
• An object can be passed to a function In the
same way as any other data type.
• Objects are passed to functions by using the
normal C++ call by-value parameter-passing
convention.
• This means that a copy of the objects and not
the object itself is passed to the function.
• Thus any changes made to the object inside the
function do NOT affect the object used as
argument to the function
Demonstration
• See passingobjects1.cpp and explain
• See passingobjectsbyRef.cpp and explain
• The comments indicate that the
modification to x within f() has no affect on
the object 0 inside main()