the queue class //this class implements a queue class queue{ int q[100];//an array of integers int...

113
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(); };

Upload: anabel-dennis

Post on 02-Jan-2016

239 views

Category:

Documents


0 download

TRANSCRIPT

The Queue class

• //this class implements a Queueclass Queue{int q[100];//an array of integersint sloc, rloc; //start location and rear locationpublic: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 slocq[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 declarationclass 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; };

int main() {ExtTime A;

return 0;}

instantiate object A of typeExtTime

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:positionspeedheading

OperationsAccelerateBreakTurnDisplayInfo

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 typesAccess 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 inheritanceProtected

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 typesAccess 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 comma-separated 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

• 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:

a) Employee | Manager | Supervisor

b) Employee / \ Manager Supervisor

C++ Syntax

class derived_class_name: public Base_class_name{ //features}Egclass 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 access-specifier: 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()