Chapter 9

121
C++ for Everyone by Cay Horstmann Copyright © 2012 by John Wiley & Sons. All rights reserved Chapter Nine: Classes Slides by Evan Gallagher

Transcript of Chapter 9

Page 1: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Chapter Nine: Classes

Slides by Evan Gallagher

Page 2: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

• To understand the concept of encapsulation• To master the separation of interface and implementation• To be able to implement your own classes • To understand how constructors and member

functions act on objects• To discover appropriate classes for solving

programming problems• To distribute a program over multiple source files

Chapter Goals

Page 3: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Some new terminology.

The data stored in an object are called:

data members

The functions that work on data members are:

member functions

No more variables and functions –

separately.

Objects to the Rescue

Page 4: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Objects to the Rescue

From now on, we’ll have only objects.

Page 5: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The data members are

encapsulated

They are hidden from other parts of the program andaccessible only through their own member functions.

Encapsulation

Page 6: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

When you use string or stream objects,

you did not know their data members.

Encapsulation means that they are hidden from you.

Encapsulation

Page 7: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

But you were allowed to call member functions

such as substr,

and you could use operatorssuch as [] or >>

(which are actually functions).

You were given an

interface

to the object.

Encapsulation and the Interface

Page 8: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

In C++, a programmer doesn’t implement a single object.

Instead, the programmer implements a class.

Classes

Page 9: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

To define a class,

you must specify the behavior

by providing implementations for the member functions,

and by defining the data members for the objects …

Defining Classes

Page 10: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Again, to define a class:

• Implement the member functions to specify the behavior.

• Define the data members to hold the object’s data.

Classes

Page 11: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

We will design a cash register object.

Designing the Class

Page 12: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

By observing a real cashier working,we realize our cash register design needs

member functions to do the following:

• Clear the cash register to start a new sale.

• Add the price of an item.

• Get the total amount owed and the count

of items purchased.

Designing the Class

Page 13: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

To define a class you write:

Classes

class NameOfClass{public: // the public interfaceprivate: // the data members};

Page 14: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Here is the C++ syntax for the CashRegister class definition:

Classes

class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: // data members will go here};

Page 15: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The public interface has the three activitiesthat we decided this object should support.

Classes

class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: // data members will go here};

Page 16: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

There are two kinds of member functions:

• Mutators

• Accessors

Methods

Page 17: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

CashRegister has two mutators:

Mutators

class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: // data members will go here};

clear

Page 18: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

CashRegister has two mutators:

Mutators

class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: // data members will go here};

clear and add_item.

Page 19: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

You call the member functions byfirst creating a variable of type CashRegister

and then using the dot notation:

Because these are mutators, the datastored in the class will be changed.

Mutators

CashRegister register1;...register1.clear();...register1.add_item(1.95);

Page 20: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Mutators

Page 21: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

CashRegister has two accessors:

Accessors

class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: // data members will go here};

get_total

Arrows in a different color would improve readability here (and on slides 58, 59, 64, and 65).
Page 22: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

CashRegister has two accessors:

Accessors

class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: // data members will go here};

and get_count.

get_total

Page 23: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

This statement will print the current total:

Accessors

cout << register1.get_total() << endl;

Page 24: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Mutators and Accessors: The Interface

The interface for our class:

Page 25: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Class Definition Syntax

Page 26: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Encapsulation

CashRegister register1;CashRegister register2;

Every CashRegister object hasa separate copy of these data members.

Page 27: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Encapsulation

Page 28: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Encapsulation

int main(){ ... cout << register1.item_count; // Error—use get_count() instead ...}

Because the data members are private, this won’t compile:

Page 29: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Encapsulation

A good design principle:

Never have any public data members.

Page 30: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Encapsulation and Methods as Guarantees

We can write the mutator for item_count so that item_count cannot be set to a negative value.

If item_count were pubic, it could be directlyset to a negative value by some misguided

(or worse, devious)programmer.

Page 31: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Encapsulation and Methods as Guarantees

There is a second benefit of encapsulation that is particularly important in larger programs:

Things Change.

Page 32: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The Interface

A driver switching to an electric cardoes not need to relearn how to drive.

Page 33: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implementing the Member Functions

The details of the add_item member function:

void add_item(double price){ item_count++; total_price = total_price + price;}

Page 34: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implementing the Member Functions

void add_item(double price){ item_count++; total_price = total_price + price;}

Page 35: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implementing the Member Functions

To specify that a function is a member functionof your class you must write

CashRegister::

in front of the member function’s name:

Page 36: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implementing the Member Functions

To specify that a function is a member functionof your class you must write

CashRegister::in front of the member function’s name:

void CashRegister::add_item(double price){ item_count++; total_price = total_price + price;}

Page 37: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implementing the Member Functions

Use CashRegister:: only when defining the

function – not in the class definition.

class CashRegister{public: ...private: ... };

void CashRegister::add_item(double price){ item_count++; total_price = total_price + price;}

Page 38: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implicit Parameters

CashRegister register2;

CashRegister register1;

Which cash register is add_item working on?

Page 39: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implicit Parameters

When a member function is called:

The variable to the left of the dot operator isimplicitly passed to the member function.

In the example, register1 is the implicit parameter.

CashRegister register1;...

register1.add_item(1.95);

Page 40: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implicit Parameters

The variable register1 is an implicit parameter.

register1.add_item(1.95);

void CashRegister::add_item(double price){ implicit parameter.item_count++; implicit parameter.total_price = implicit parameter.total_price + price;}

Page 41: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Implicit Parameters

Page 42: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Calling a Member Function from a Member Function

void CashRegister::add_items(int qnt, double prc){ for (int i = 1; i <= qnt; i++) { add_item(prc); }}

Page 43: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Calling a Member Function from a Member Function

Page 44: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The Cash Register Program

#include <iostream>#include <iomanip>using namespace std;/** A simulated cash register that tracks the item count and the total amount due.*/class CashRegister{public:

ch09/registertest1.cpp

Page 45: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The Cash Register Program

class CashRegister{public: /** Clears the item count and the total. */ void clear();

/** Adds an item to this cash register. @param price the price of this item */ void add_item(double price);

ch09/registertest1.cpp

Page 46: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The Cash Register Program

/** @return the total amount of the current sale */ double get_total() const;

/** @return the item count of the current sale */ int get_count() const;

private: int item_count; double total_price;};

ch09/registertest1.cpp

Page 47: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The Cash Register Program

void CashRegister::clear() { item_count = 0; total_price = 0; } void CashRegister::add_item(double price) { item_count++; total_price = total_price + price; } double CashRegister::get_total() const { return total_price; }

ch09/registertest1.cpp

Page 48: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The Cash Register Program

int CashRegister::get_count() const { return item_count; }

/** Displays the item count and total price of a cash register. @param reg the cash register to display */ void display(CashRegister reg) { cout << reg.get_count() << " $“ << fixed << setprecision(2) << reg.get_total() << endl; }

ch09/registertest1.cpp

Page 49: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The Cash Register Program

int main(){ CashRegister register1; register1.clear(); register1.add_item(1.95); display(register1); register1.add_item(0.95); display(register1); register1.add_item(2.50); display(register1); return 0;}

ch09/registertest1.cpp

Page 50: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

A friendly construction worker

reading a class definition

House house1;House house2;House house3;...

Page 51: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

A constructor is a member function that initializes the data members of an object.

(It doesn’t construct?)

Page 52: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

The constructor is automaticallycalled whenever an object is created.

CashRegister register1;

Page 53: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

To understand the importance of constructors,consider the following statements:

CashRegister register1;

register1.add_item(1.95);

int count = get_count(); // May not be 1

Notice that the programmer forgot tocall clear before adding items.

Page 54: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

You declare constructors in the class definition:

class CashRegister{public: CashRegister(); // A constructor...};

Page 55: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

The name of a constructor is identical to the name of its class:

class CashRegister{public: CashRegister(); // A constructor...};

Page 56: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

There must be no return type, not even void.

class CashRegister{public: CashRegister(); // A constructor...};

Page 57: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

And, of course, you must define the constructor.

CashRegister::CashRegister(){ item_count = 0; total_price = 0;}

Page 58: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

Default constructors are called when you define an object

and do not specify any parameters for the construction.

Notice that you do NOT use an empty set of parentheses.

CashRegister register1;

Page 59: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

Constructors can have parameters,and constructors can be overloaded:

class BankAccount{public: // Sets balance to 0 BankAccount(); // Sets balance to initial_balance BankAccount(double initial_balance); // Member functions omittedprivate: double balance;};

Page 60: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Constructors

When you construct an object, the compiler chooses the constructor that matches the parameters that you supply:

BankAccount joes_account; // Uses default constructorBankAccount lisas_account(499.95); // Uses BankAccount(double) constructor

Page 61: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Common Error: Trying to Use the Constructor to Reset

You cannot use a constructor to “reset” a variable.

It seems like a good idea but you can’t:

CashRegister register1;...register1.CashRegister(); // Error

Page 62: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Initialization Lists

A class to represent an order might not havea default constructor:

class Item:public: Item(string item_descript, double item_price); // No other constructors ...};

Page 63: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Initialization Lists

A class to represent an order would most likelyhave an Item type data member:

class Order{public: Order(string customer_name, string item_descript, double item_price);...private: Item article; string customer;};

Page 64: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Initialization Lists

The Order constructor must call the Item constructor.

This is done in the initializer list.

The initializer list goes before the opening brace of the constructor by putting the name of the data memberfollowed by their construction arguments:

Order::Order(string customer_name, string item_description, double item_price) : article(item_description, item_price) ...

Page 65: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Initialization Lists

Any other data members can also be initialized in the initializer list by putting their initial values in parentheses after their name, just like the class type data members.These must be separated by commas:

Order::Order(string customer_name, string item_description, double item_price) : article(item_description, item_price), customer(customer_name){}

Notice there’s nothing to do in the body of the constructor now.

Page 66: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

You know that the public: section is for others.That’s where you’ll write methods for their use.

That will be the front of the card.class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: int item_count; double total_price;};

...

CashRegister reg1;

Page 67: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

You know that the private: section is for your data – they are not allowed to mess with itexcept through the public methods you provide.

That will be the back of the card.class CashRegister{public: void clear(); void add_item(double price); double get_total() const; int get_count() const;private: int item_count; double total_price;};

...

CashRegister reg1;

Page 68: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

When an object is constructed,add the variable’s name to the front of a card

and fill in the initial values.

0 0

CashRegister reg1;

Page 69: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

You would do this for every variable.

0 0

0 0

CashRegister reg1;CashRegister reg2;

Page 70: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

When a method is invoked,grab the right card...

0 0

0 0

CashRegister reg1;CashRegister reg2;reg1.addItem(19.95);

Page 71: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

…flip it over…

0 0

0 0

CashRegister reg1;CashRegister reg2;reg1.addItem(19.95);

Page 72: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

…cross out the old values...

0 0

0 0

CashRegister reg1;CashRegister reg2;reg1.addItem(19.95);

Page 73: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

…then write the new values below.

0 0 1 19.95

0 0

CashRegister reg1;CashRegister reg2;reg1.addItem(19.95);

Page 74: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Tracing Objects

Add these things and do some tracing.

CashRegister reg2(TAX_RATE);reg2.addItem(3.95, false);reg2.addItem(19.95, true);

Page 75: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Discovering Classes

• nouns correspond to classes, and

• verbs correspond to member functions.

Page 76: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Discovering Classes

Many classes are abstractions of real-life entities.

• BankAccount

• CashRegister

Page 77: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Not Discovering Classes

If you can’t tell from the class name what

an object of the class is supposed to do,

then you are probably not on the right track.

Page 78: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Not Discovering Classes

For example, you might be asked to write a program that prints paychecks.

You start by trying to design aclass PaycheckProgram.

Page 79: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Not Discovering Classes

class PaycheckProgram

? ?

An object of this class would have to

do everything!

Page 80: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Discovering Classes

class Paycheck

! ! ! ! !

Page 81: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Not Discovering Classes

Another common mistake, made particularlyby those who are used to writing programs that consist

of functions, is to turn an action into a class.

Page 82: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Not Discovering Classes

For example, if you are to computea paycheck, you might consider writing a

class ComputePaycheck.

Page 83: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Not Discovering Classes

class ComputePaycheck

But can you visualize a“ComputePaycheck” object?

A thing that is a computePaycheck?

Page 84: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Not Discovering Classes

“paycheck”

Page 85: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Discovering Classes

You can visualize a paycheck object.

You can then think about useful member functionsof the Paycheck class, such as compute_taxes,

that help you solve the problem.

Page 86: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

“Has-a” relationship

The aggregation relationship states that objects of one class contain objects of another class.

Page 87: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

“Has-a” relationship

Consider a quiz that is made up of questions.

Since each quiz has one or more questions,we say that the class Quiz aggregates the class Question

Page 88: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

UML (Unified Modeling Language)

There is a standard notation to describe class relationships:

a UML class diagram

(Unified Modeling Language)

Page 89: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

UML (Unified Modeling Language)

In the UML notation,aggregation is denoted by a linewith a diamond-shaped symbol

Page 90: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The problem states that the Quiz objectmanages lots of Question objects.

The code follows directly, using a vector to mangethe Questions:

class Quiz

{

};

UML (Unified Modeling Language)

...private:vector<Question> questions;

Page 91: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation

If your program is composed of multiple files, some of these files will define data types or

functions that are needed in other files.

There must be a path of communication between the files.

In C++, that communication happens throughthe inclusion of header files.

Yes, #include.

Page 92: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation

The code will be in two kinds of files:

header files

(which will be #include-ed)

source files

(which should never be #include-ed)

Page 93: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation

A header file contains

• the interface: – Definitions of classes.– Definitions of constants.– Declarations of nonmember functions.

Page 94: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation

A source file contains

• the implementation:– Definitions of member functions.– Definitions of nonmember functions.

Page 95: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation

For the CashRegister class,you create a pair of files:

cashregister.h

the interface – the class definition

cashregister.cpp

the implementation – all the member function definitions

Page 96: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

#ifndef CASHREGISTER_H#define CASHREGISTER_H

/** A simulated cash register that tracks the item count and the total amount due.*/class CashRegister

This is the header file, cashregister.h

ch09/cashregister.h

Page 97: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

/** A simulated cash register that tracks the item count and the total amount due.*/class CashRegister{public: /** Constructs a cash register with cleared item count and total. */ CashRegister(); /** Clears the item count and the total. */ void clear();

ch09/cashregister.h

Page 98: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

/** Adds an item to this cash register. @param price the price of this item */ void add_item(double price); /** @return the total amount of the current sale */ double get_total() const; /** @return the item count of the current sale */ int get_count() const;

ch09/cashregister.h

Page 99: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

private: int item_count; double total_price;};

#endif

You include this header file whenever the definitionof the CashRegister class is required.Since this file is not a standard header file, you must enclose its name in quotes, not <...>, when you include it, like this:

#include "cashregister.h"

And now the implementation (.cpp) file:

ch09/cashregister.h

Page 100: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

#include "cashregister.h"

CashRegister::CashRegister(){ clear();}

void CashRegister::clear(){ item_count = 0; total_price = 0;}

Notice that the implementationfile #includes its own header file.

ch09/cashgregister.cpp

Page 101: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

void CashRegister::add_item(double price){ item_count++; total_price = total_price + price;}

double CashRegister::get_total() const{ return total_price;}int CashRegister::get_count() const{ return item_count;}

ch09/cashgregister.cpp

Page 102: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation

There’s no main!

No, someone who wants to use your class will writetheir own main and #include your header.

Like this:

Page 103: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

#include <iostream>#include <iomanip>#include "cashregister.h"using namespace std;

/** Displays the item count and total price of a cash register. @param reg the cash register to display*/void display(CashRegister reg){ cout << reg.get_count() << " $“ << fixed << setprecision(2) << reg.get_total() << endl;}

ch09/registertest2.cpp

Page 104: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Separate Compilation: The Cash Register Program

int main(){ CashRegister register1; register1.clear(); register1.add_item(1.95); display(register1); register1.add_item(0.95); display(register1); register1.add_item(2.50); display(register1); return 0;}

ch09/registertest2.cpp

Page 105: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Pointers to Objects

CashRegister* register_pointer = new CashRegister;

BankAccount* account_pointer = new BankAccount(1000);

Page 106: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Accessing: The -> Operator

Because register_pointer is a pointerto a CashRegister object,

the value *register_pointer denotesthe CashRegister object itself.

To invoke a member function on that object, you might call

(*register_pointer).add_item(1.95);

Page 107: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Pointers to Objects

Because calling a member function through a pointer is very

common, the designers of C++ supply an operator to abbreviate

the “follow pointer and access member” operation.

That operator is written -> and usually pronounced as “arrow”.

Here is how you use the “arrow” operator:

register_pointer->add_item(1.95);

Page 108: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this Pointer

Each member function has a special parameter variable,called this,

which is a pointer to the implicit parameter.

Page 109: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this Pointer

For example, consider the member function

CashRegister::add_item

Page 110: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

void CashRegister::add_item(double price)

{

this->item_count++;

this->total_price = this->total_price + price;

}

The this Pointer

Page 111: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this Pointer

void CashRegister::add_item(double price)

{

this->item_count++;

this->total_price = this->total_price + price;

}

this points at the implicit parameter.

Page 112: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this pointer is not necessary here, but some

programmers like to use the this pointer to make

it very, very clear that item_count is a

data member and not a variable.

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

The this Pointer

void CashRegister::add_item(double price)

{

this->item_count++;

this->total_price = this->total_price + price;

}

The this pointer is not necessary here, but some programmers like to use the this pointer to make it

very, very clearthat item_count and total_price are

data members—not (plain old) variables or parameters.

Page 113: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

class String

{

...

private:

char* char_array;

}

String::String(const char initial_chars[])

{

char_array = new char[strlen(initial_chars) + 1];

strcpy(char_array, initial_chars);

}

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

The characters of a String are stored on the heap,

a system resource.

Page 114: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this pointer is not necessary here, but some

programmers like to use the this pointer to make

it very, very clear that item_count is a

data member and not a variable.

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

A destructor, like a constructor, is written

without a return type and its name is

the tilde character followed by the name of the class:

~ String

Page 115: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this pointer is not necessary here, but some

programmers like to use the this pointer to make

it very, very clear that item_count is a

data member and not a variable.

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

A class can have only one destructor

and

it cannot have any parameters.

String::~ String() { ...

Page 116: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this pointer is not necessary here, but some

programmers like to use the this pointer to make

it very, very clear that item_count is a

data member and not a variable.

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

Destructors don’t really destruct:

they are used to recycle resources.

String::~ String() { ...

Page 117: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

The this pointer is not necessary here, but some

programmers like to use the this pointer to make

it very, very clear that item_count is a

data member and not a variable.

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

Destructors don’t really destruct:

they are used to recycle resources.

String::~ String() {

delete[] char_array;

}

Page 118: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Destructors are automatically invoked whenan object of that type is no longer needed.

The memory for the characters in a string are properly recycled..

void fun()

{

String name("Harry");

...

}

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

String::~String() is invoked right there.

Page 119: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

Unfortunately, it’s a more complicatedwhen assignment comes along:

void no_fun()

{

String name1("Harry");

String name2("Sally");

name1 = name2;

...

}

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

Heap memory is memory is allocated by both allocated by both the constructorsthe constructors

What happened to the memory for “Harry”?

Now what?!

Page 120: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

This is not a topic covered in these slides.

It involves:the destructor

andanother kind of constructor - the copy constructor

andrewriting how the assignment operation works.

These three topics together are called The Big Three.

C++ for Everyone by Cay HorstmannCopyright © 2008 by John Wiley & Sons. All rights reserved

Destructors and Resource Management

Page 121: Chapter 9

C++ for Everyone by Cay HorstmannCopyright © 2012 by John Wiley & Sons. All rights reserved

End Chapter Nine

Slides by Evan Gallagher