Chapter 13 Introduction to Classes
13.1 Procedural and Object-Oriented Programming
Concept:
Procedural programming centers on the procedures or actions within a program.
Object-oriented programming (OOP) revolves around objects, which are created from abstract data types that bundle data and functions.
Two primary programming methods exist: procedural programming and object-oriented programming (OOP).
In a procedural program, data (stored in variables/structures) and the functions that operate on that data are separate. The main focus is on creating these functions.
A key challenge in procedural programming arises when data structures change. This forces modifications to all functions that operate on that data, which can lead to bugs.
OOP was developed to address this issue. It centers on creating objects, which are self-contained software entities that combine both data and procedures.
- Attributes: The data contained within an object.
- Member Functions: The procedures an object can perform. (Also called methods in other languages).
OOP introduces key concepts to solve the problems of procedural programming:
- Encapsulation: The bundling of data and code into a single object.
- Data Hiding: An object’s ability to conceal its internal data from outside code. Only the object’s own member functions can directly access its data, protecting it from accidental corruption.
The member functions of an object provide a public interface, allowing outside code to interact with the object’s data indirectly and safely.
This is analogous to driving a car: the driver uses a simple interface (steering wheel, pedals) without needing to know the complex internal mechanics. The interface protects the car’s engine and makes it easy to use.
Object Reusability
OOP promotes object reusability. An object is not a standalone program but a component that can be used by any program needing its services.
For example, a programmer can create a specialized 3D graphics object that other developers can then use in their own applications without needing to understand the complex math involved.
Classes and Objects
An object is created from a class. A class is a programmer-defined blueprint that specifies the attributes and member functions a type of object will have.
A class is not an object itself, but a description of one.
An object is an instance of a class. When a program runs, it uses the class to create one or more objects in memory.
Each object created from a class is a separate entity with its own set of attributes, as specified by the class blueprint.
For example, a procedural rectangle program would have separate variables for
widthandlengthand separate functions to manipulate them.In an OOP approach, we would create a
Rectangleclass that encapsulates both the data (width,length) and the functions (setWidth,getArea, etc.) into a single unit.
Using a Class You Already Know
The
stringclass is a familiar example. To use it, you must include the<string>header file.Defining a
stringobject is an example of creating an instance of thestringclass.
string cityName;- You can assign data to the object’s attributes.
cityName = "Charleston";The
stringclass provides member functions to operate on the object’s data. You call these functions using the dot operator (.).The
lengthmember function returns the number of characters in the string.
int strSize;
strSize = cityName.length(); - The
appendmember function adds text to the end of the existing string.
cityName.append(" South Carolina");13.2 Introduction to Classes
Concept:
- In C++, a class is the primary construct for creating objects. It is similar to a structure but with enhanced features.
Writing a Class
- A class is a programmer-defined data type composed of variables and functions. The general format for a class declaration is:
class ClassName
{
declaration;
};- By default, all members of a class are private, meaning they cannot be accessed by code outside the class.
class Rectangle
{
double width;
double length;
}; - This default privacy enforces data hiding, a core principle of OOP.
Access Specifiers
C++ uses the keywords
privateandpublicas access specifiers to control how class members can be accessed.privatemembers can only be accessed by member functions of the same class.publicmembers can be accessed by code outside the class.
The general format using access specifiers is:
class ClassName
{
private:
public:
};Public Member Functions
To allow controlled access to private member variables, you create public member functions that operate on them.
For our
Rectangleclass, we can declare public functions to set and get the width and length, and to calculate the area.The function declarations, or prototypes, are placed inside the class declaration.
class Rectangle
{
private:
double width;
double length;
public:
void setWidth(double);
void setLength(double);
double getWidth() const;
double getLength() const;
double getArea() const;
};- In this structure, the
privatevariables (width,length) are protected. Outside code must use thepublicfunctions to interact with the object’s data.
Using const with Member Functions
- The
constkeyword appearing after a member function’s parentheses indicates that the function will not modify the object’s data.
double getWidth() const;This is a safety feature. If you accidentally write code inside a
constfunction that changes member data, the compiler will report an error.The
constkeyword must be used in both the function declaration (prototype) and its definition.
Placement of public and privateMembers
There is no strict rule about ordering
publicandprivatesections.However, for consistency and readability, most programmers group all members with the same access specification together.
Defining Member Functions
The definitions of member functions are typically written outside the class declaration.
To associate a function definition with its class, you must use the class name and the scope resolution operator (
::).
void Rectangle::setWidth(double w)
{
width = w;
}- The general format for a member function header defined outside the class is:
ReturnType ClassName::functionName(ParameterList)- The class name and scope resolution operator are essential; without them, the function would not be recognized as a member of the class.
Accessors and Mutators
It’s common practice to make member variables private and provide public functions to access them.
- An accessor is a member function that gets a value from a member variable but does not change it. These are often called “getter” functions.
- A mutator is a member function that stores a value in a member variable or changes its value. These are often called “setter” functions.
In the
Rectangleclass:getWidthandgetLengthare accessors.setWidthandsetLengthare mutators.
Using const with Accessors
Accessor functions, by definition, should not change an object’s data.
It is a good programming practice to mark all accessor functions as
constto prevent accidental modifications and reduce bugs.
double Rectangle::getWidth() const
{
return width;
}The Importance of Data Hiding
Data hiding is crucial in large-scale software development.
When other programmers use your classes, making data private and accessible only through public member functions ensures your class is used as intended and prevents its data from being corrupted.
13.3 Defining an Instance of a Class
Concept:
- A class declaration is just a blueprint. Class objects must be defined to be created in memory.
Defining an Instance of a Class
Class objects are defined similarly to variables, using the class name as the data type. This process is called instantiation.
The general format is:
ClassName objectName;- For example, to create an object (an instance) of the
Rectangleclass namedbox:
Rectangle box;Accessing an Object’s Members
The dot operator (
.) is used to access an object’s public members, such as calling its member functions.To set the
widthof theboxobject, you call itssetWidthmember function:
box.setWidth(12.7);- Other examples include:
box.setLength(4.8);
x = box.getWidth();
cout << box.getLength();
cout << box.getArea(); - Inside a member function, the dot operator is not needed to access the member variables of the calling object.
A Class Demonstration Program
- The following program demonstrates the complete
Rectangleclass and its usage.
🗊 Program 13-1
#include <iostream>
using namespace std;
class Rectangle
{
private:
double width;
double length;
public:
void setWidth(double);
void setLength(double);
double getWidth() const;
double getLength() const;
double getArea() const;
};
void Rectangle::setWidth(double w)
{
width = w;
}
void Rectangle::setLength(double len)
{
length = len;
}
double Rectangle::getWidth() const
{
return width;
}
double Rectangle::getLength() const
{
return length;
}
double Rectangle::getArea() const
{
return width * length;
}
int main()
{
Rectangle box;
double rectWidth;
double rectLength;
cout << "This program will calculate the area of a\n";
cout << "rectangle. What is the width? ";
cin >> rectWidth;
cout << "What is the length? ";
cin >> rectLength;
box.setWidth(rectWidth);
box.setLength(rectLength);
cout << "Here is the rectangle's data:\n";
cout << "Width: " << box.getWidth() << endl;
cout << "Length: " << box.getLength() << endl;
cout << "Area: " << box.getArea() << endl;
return 0;
}💻 Program Output
When a
Rectangleobject likeboxis defined, its member variables are uninitialized and hold garbage values.An object’s state refers to the data stored in its attributes at any given moment. The program uses mutator functions (
setWidth,setLength) to change the state of theboxobject.You can create multiple instances of the same class. Each object will have its own set of member variables in memory.
🗊 Program 13-2
#include <iostream>
using namespace std;
Lines 6 through 62 have been left out.
int main()
{
double number;
double totalArea;
Rectangle kitchen;
Rectangle bedroom;
Rectangle den;
cout << "What is the kitchen's length? ";
cin >> number;
kitchen.setLength(number);
cout << "What is the kitchen's width? ";
cin >> number;
kitchen.setWidth(number);
cout << "What is the bedroom's length? ";
cin >> number;
bedroom.setLength(number);
cout << "What is the bedroom's width? ";
cin >> number;
bedroom.setWidth(number);
cout << "What is the den's length? ";
cin >> number;
den.setLength(number);
cout << "What is the den's width? ";
cin >> number;
den.setWidth(number);
totalArea = kitchen.getArea() + bedroom.getArea() +
den.getArea();
cout << "The total area of the three rooms is "
<< totalArea << endl;
return 0;
}💻 Program Output
- In Program 13-2,
kitchen,bedroom, anddenare three distinctRectangleobjects, each with its ownlengthandwidth.
Avoiding Stale Data
Data is considered stale if it depends on other data and is not updated when that other data changes.
In the
Rectangleclass, the area is calculated by thegetAreafunction rather than being stored in a member variable.If area were a member variable, it would become stale every time
widthorlengthchanged.As a design principle, avoid storing calculated data in member variables. Instead, provide a member function to perform the calculation and return the result.
Pointers to Objects
- You can define pointers that hold the memory address of a class object.
Rectangle myRectangle;
Rectangle *rectPtr = nullptr;
rectPtr = &myRectangle;- To access an object’s members through a pointer, use the
->operator.
rectPtr->setWidth(12.5);
rectPtr->setLength(4.8);Pointers are commonly used to dynamically allocate objects using the
newoperator.Remember to use the
deleteoperator to free the memory allocated for the object when it is no longer needed.
🗊 Program 13-3
#include <iostream>
using namespace std;
Lines 6 through 62 have been left out.
int main()
{
double number;
double totalArea;
Rectangle *kitchen = nullptr;
Rectangle *bedroom = nullptr;
Rectangle *den = nullptr;
kitchen = new Rectangle;
bedroom = new Rectangle;
den = new Rectangle;
cout << "What is the kitchen's length? ";
cin >> number;
kitchen->setLength(number);
cout << "What is the kitchen's width? ";
cin >> number;
kitchen->setWidth(number);
cout << "What is the bedroom's length? ";
cin >> number;
bedroom->setLength(number);
cout << "What is the bedroom's width? ";
cin >> number;
bedroom->setWidth(number);
cout << "What is the den's length? ";
cin >> number;
den->setLength(number);
cout << "What is the den's width? ";
cin >> number;
den->setWidth(number);
totalArea = kitchen->getArea() + bedroom->getArea() +
den->getArea();
cout << "The total area of the three rooms is "
<< totalArea << endl;
delete kitchen;
delete bedroom;
delete den;
kitchen = nullptr;
bedroom = nullptr;
den = nullptr;
return 0;
}Using Smart Pointers to Allocate Objects
C++ 11 introduced smart pointers, like
unique_ptr, which automatically manage dynamically allocated memory.This helps prevent memory leaks because the memory is automatically deleted when it’s no longer in use.
To use
unique_ptr, you must include the<memory>header file.The syntax to define a
unique_ptrfor aRectangleobject is:
#include <memory>
unique_ptr<Rectangle> rectanglePtr(new Rectangle);Once defined, a
unique_ptrcan be used like a regular pointer with the->operator.No
deletestatement is needed, as the smart pointer handles memory deallocation automatically when it goes out of scope.
🗊 Program 13-4
#include <iostream>
#include <memory>
using namespace std;
Lines 8 through 64 have been left out.
int main()
{
double number;
double totalArea;
unique_ptr<Rectangle> kitchen(new Rectangle);
unique_ptr<Rectangle> bedroom(new Rectangle);
unique_ptr<Rectangle> den(new Rectangle);
cout << "What is the kitchen's length? ";
cin >> number;
kitchen->setLength(number);
cout << "What is the kitchen's width? ";
cin >> number;
kitchen->setWidth(number);
cout << "What is the bedroom's length? ";
cin >> number;
bedroom->setLength(number);
cout << "What is the bedroom's width? ";
cin >> number;
bedroom->setWidth(number);
cout << "What is the den's length? ";
cin >> number;
den->setLength(number);
cout << "What is the den's width? ";
cin >> number;
den->setWidth(number);
totalArea = kitchen->getArea() + bedroom->getArea() +
den->getArea();
cout << "The total area of the three rooms is "
<< totalArea << endl;
return 0;
}Checkpoint
13.1 True or False: You must declare all private members of a class before the public members.
13.2 Assume
RetailItemis the name of a class, and the class has avoidmember function namedsetPrice, which accepts adoubleargument. Which of the following shows the correct use of the scope resolution operator in the member function definition?RetailItem::void setPrice(double p)void RetailItem::setPrice(double p)
13.3 An object’s private member variables are accessed from outside the object by which of the following?
public member functions
any function
the dot operator
the scope resolution operator
13.4 Assume
RetailItemis the name of a class, and the class has avoidmember function namedsetPrice, which accepts adoubleargument. Ifsoapis an instance of theRetailItemclass, which of the following statements properly uses thesoapobject to call thesetPricemember function?RetailItem::setPrice(1.49);soap::setPrice(1.49);soap.setPrice(1.49);soap:setPrice(1.49);
13.5 Complete the following code skeleton to declare a class named
Date. The class should contain variables and functions to store and retrieve a date in the form 4/2/2018.class Date { private: public: }
13.4 Why Have Private Members?
Concept:
- An object should protect its important data by making it
privateand providing apublicinterface for access.
Making member variables
privateprotects critical data from being accidentally modified or used improperly.When a member is
private, the only way to access it from outside the class is through a public member function.These public functions act as a controlled interface to the object’s data.
A major benefit of this approach is that mutator functions can perform data validation before storing a value in a private member variable.
For example, the
setWidthfunction can be modified to ensure that only non-negative values are assigned to thewidthmember.
void Rectangle::setWidth(double w)
{
if (w >= 0)
width = w;
else
{
cout << "Invalid width\n";
exit(EXIT_FAILURE);
}
}- This ensures that only acceptable data is stored in the object’s attributes, maintaining the object’s integrity.
13.5 Focus on Software Engineering: Separating Class Specification from Implementation
Concept:
- It is standard practice to store class declarations in header (
.h) files and member function definitions in implementation (.cpp) files.
A more conventional way to structure C++ programs is to separate class components into different files:
- Class Specification File: A header file (e.g.,
Rectangle.h) that contains the class declaration. - Class Implementation File: A
.cppfile (e.g.,Rectangle.cpp) that contains the definitions of the class’s member functions. - Main Program File: A
.cppfile (e.g.,main.cpp) that uses the class to solve a problem.
- Class Specification File: A header file (e.g.,
Any program that uses the class must
#includethe class’s header file. The implementation.cppfile is then compiled and linked with the main program to create an executable.
Contents of Rectangle.h (Version 1)
- The
#ifndef RECTANGLE_Hand#define RECTANGLE_Hpreprocessor directives form an include guard.- An include guard prevents the header file from being included more than once in the same program, which would cause compilation errors.
ifndefstands for “if not defined.” If the constantRECTANGLE_His not defined, the code up to#endifis processed, andRECTANGLE_His defined.- On subsequent inclusion attempts, the constant will already be defined, and the preprocessor will skip the file’s contents.
Contents of Rectangle.cpp (Version 1)
#include "Rectangle.h"
#include <iostream>
#include <cstdlib>
using namespace std;
void Rectangle::setWidth(double w)
{
if (w >= 0)
width = w;
else
{
cout << "Invalid width\n";
exit(EXIT_FAILURE);
}
}
void Rectangle::setLength(double len)
{
if (len >= 0)
length = len;
else
{
cout << "Invalid length\n";
exit(EXIT_FAILURE);
}
}
double Rectangle::getWidth() const
{
return width;
}
double Rectangle::getLength() const
{
return length;
}
double Rectangle::getArea() const
{
return width * length;
}The implementation file must
#includeits corresponding specification file ("Rectangle.h").- Use double quotes (
" ") for header files you have written, which are typically in the current project directory. - Use angle brackets (
< >) for standard C++ library files, which are in the compiler’s include directory.
- Use double quotes (
The following program uses the separated
Rectangleclass.
🗊 Program 13-5
#include <iostream>
#include "Rectangle.h"
using namespace std;
int main()
{
Rectangle box;
double rectWidth;
double rectLength;
cout << "This program will calculate the area of a\n";
cout << "rectangle. What is the width? ";
cin >> rectWidth;
cout << "What is the length? ";
cin >> rectLength;
box.setWidth(rectWidth);
box.setLength(rectLength);
cout << "Here is the rectangle's data:\n";
cout << "Width: " << box.getWidth() << endl;
cout << "Length: " << box.getLength() << endl;
cout << "Area: " << box.getArea() << endl;
return 0;
}To create an executable file from this multi-file project, the following steps are required:
- Compile the implementation file (
Rectangle.cpp) into an object file (Rectangle.obj). - Compile the main program file (
Pr13–5.cpp) into its own object file (Pr13–5.obj). - Link the object files (
Rectangle.objandPr13–5.obj) together to create a final executable file (Pr13–5.exe).
- Compile the implementation file (
Most modern Integrated Development Environments (IDEs) automate this compilation and linking process when you build a project.
This separation provides flexibility:
- You can share your class with other programmers by giving them only the specification file and the compiled object file, keeping your source code private.
- If you need to modify a member function, you only need to change and recompile the implementation file. Programs using the class only need to be re-linked, not completely recompiled.
13.6 Inline Member Functions
Concept:
- When a member function’s body is defined inside a class declaration, it becomes an inline function.
For member functions with small bodies, it’s often more convenient to place the full definition inside the class declaration instead of just a prototype.
This approach is demonstrated below with the
getWidth,getLength, andgetAreafunctions in theRectangleclass.
Contents of Rectangle.h (Version 2)
When a function is defined this way, it’s called an inline function.
The scope resolution operator (
::) is not needed because the definition is already within the class’s scope.Functions can be mixed; some can be inline while others are defined externally in the implementation file.
Contents of Rectangle.cpp (Version 2)
#include "Rectangle.h"
#include <iostream>
#include <cstdlib>
using namespace std;
void Rectangle::setWidth(double w)
{
if (w >= 0)
width = w;
else
{
cout << "Invalid width\n";
exit(EXIT_FAILURE);
}
}
void Rectangle::setLength(double len)
{
if (len >= 0)
length = len;
else
{
cout << "Invalid length\n";
exit(EXIT_FAILURE);
}
}Inline Functions and Performance
A conventional function call has processing overhead, such as storing arguments and a return address on the stack.
While this overhead is small, it can become significant if a function is called many times, such as inside a loop.
Inline functions are handled differently by the compiler. Through a process called inline expansion, the compiler replaces the function call with the actual code of the function.
- Benefit: This eliminates the function call overhead, which can improve performance.
- Drawback: This can increase the size of the final executable program because the function’s code is duplicated at each call site.
Checkpoint
13.6 Why would you declare a class’s member variables
private?13.7 When a class’s member variables are declared
private, how does code outside the class store values in, or retrieve values from, the member variables?13.8 What is a class specification file? What is a class implementation file?
13.9 What is the purpose of an include guard?
13.10 Assume the following class components exist in a program:
BasePayclass declarationBasePaymember function definitionsOvertimeclass declarationOvertimemember function definitionsIn what files would you store each of these components?
13.11 What is an inline member function?
13.7 Constructors
Concept:
- A constructor is a special member function that is automatically called when a class object is created (instantiated).
A constructor is a member function that shares the same name as its class.
It is automatically executed when an object of the class is created and is typically used for initialization.
Key characteristics of a constructor:
- It has the same name as the class.
- It has no return type, not even
void. - It cannot be called explicitly and cannot return a value.
The following program demonstrates a simple constructor.
🗊 Program 13-6
💻 Program Output
The constructor is called automatically at the point where the object is defined.
The primary purpose of a constructor is to initialize an object’s attributes to valid starting values, preventing them from holding garbage data.
It’s good practice to provide a constructor for every class you create.
The
Rectangleclass below is improved with a constructor that initializeswidthandlengthto 0.0.
Contents of Rectangle.h (Version 3)
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle
{
private:
double width;
double length;
public:
Rectangle();
void setWidth(double);
void setLength(double);
double getWidth() const
{ return width; }
double getLength() const
{ return length; }
double getArea() const
{ return width * length; }
};
#endifContents of Rectangle.cpp (Version 3)
#include "Rectangle.h"
#include <iostream>
#include <cstdlib>
using namespace std;
Rectangle::Rectangle()
{
width = 0.0;
length = 0.0;
}
void Rectangle::setWidth(double w)
{
if (w >= 0)
width = w;
else
{
cout << "Invalid width\n";
exit(EXIT_FAILURE);
}
}
void Rectangle::setLength(double len)
{
if (len >= 0)
length = len;
else
{
cout << "Invalid length\n";
exit(EXIT_FAILURE);
}
}🗊 Program 13-7
💻 Program Output
Using Member Initialization Lists
As an alternative to assignment statements inside the constructor’s body, you can use a member initialization list.
This technique initializes members in the function header, following a colon (
:).Many programmers prefer this method as it can sometimes be more efficient.
Rectangle::Rectangle() :
width(0.0), length(0.0)
{
}- Initializations in the list occur before any statements in the constructor’s body are executed.
In-Place Member Initialization
- C++ 11 introduced in-place initialization, which allows you to initialize a member variable directly in its declaration statement, just like a regular variable.
class Rectangle
{
private:
double width = 0.0;
double length = 0.0;
public:
};The Default Constructor
A default constructor is a constructor that takes no arguments.
If you do not provide any constructor for a class, C++ automatically generates a default constructor that does nothing.
Default Constructors and Dynamically Allocated Objects
- When an object is dynamically allocated with the
newoperator, its default constructor is automatically called.
Rectangle *rectPtr = nullptr;
rectPtr = new Rectangle; 13.8 Passing Arguments to Constructors
Concept:
- Constructors can have parameters, allowing you to pass arguments to them when an object is created.
A constructor can be designed to accept arguments, which allows you to provide initial values for member variables at the time an object is defined.
Arguments are passed in parentheses following the object’s name in the definition statement.
Rectangle box(10.0, 12.0); - The following version of the
Rectangleclass includes a constructor that accepts arguments for width and length.
Contents of Rectangle.h (Version 4)
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle
{
private:
double width;
double length;
public:
Rectangle(double, double);
void setWidth(double);
void setLength(double);
double getWidth() const
{ return width; }
double getLength() const
{ return length; }
double getArea() const
{ return width * length; }
};
#endifContents of Rectangle.cpp (Version 4)
#include "Rectangle.h"
#include <iostream>
#include <cstdlib>
using namespace std;
Rectangle::Rectangle(double w, double len)
{
width = w;
length = len;
}
void Rectangle::setWidth(double w)
{
if (w >= 0)
width = w;
else
{
cout << "Invalid width\n";
exit(EXIT_FAILURE);
}
}
void Rectangle::setLength(double len)
{
if (len >= 0)
length = len;
else
{
cout << "Invalid length\n";
exit(EXIT_FAILURE);
}
}🗊 Program 13-8
#include <iostream>
#include <iomanip>
#include "Rectangle.h"
using namespace std;
int main()
{
double houseWidth,
houseLength;
cout << "In feet, how wide is your house? ";
cin >> houseWidth;
cout << "In feet, how long is your house? ";
cin >> houseLength;
Rectangle house(houseWidth, houseLength);
cout << setprecision(2) << fixed;
cout << "The house is " << house.getWidth()
<< " feet wide.\n";
cout << "The house is " << house.getLength()
<< " feet long.\n";
cout << "The house is " << house.getArea()
<< " square feet in area.\n";
return 0;
}💻 Program Output
- The following
Saleclass provides another example of a constructor that accepts arguments.
Contents of Sale.h (Version 1)
#ifndef SALE_H
#define SALE_H
class Sale
{
private:
double itemCost;
double taxRate;
public:
Sale(double cost, double rate)
{ itemCost = cost;
taxRate = rate; }
double getItemCost() const
{ return itemCost; }
double getTaxRate() const
{ return taxRate; }
double getTax() const
{ return (itemCost * taxRate); }
double getTotal() const
{ return (itemCost + getTax()); }
};
#endif🗊 Program 13-9
#include <iostream>
#include <iomanip>
#include "Sale.h"
using namespace std;
int main()
{
const double TAX_RATE = 0.06;
double cost;
cout << "Enter the cost of the item: ";
cin >> cost;
Sale itemSale(cost, TAX_RATE);
cout << fixed << showpoint << setprecision(2);
cout << "The amount of sales tax is $"
<< itemSale.getTax() << endl;
cout << "The total of the sale is $";
cout << itemSale.getTotal() << endl;
return 0;
}💻 Program Output
Using Default Arguments with Constructors
Like regular functions, constructors can have default arguments.
If an argument is omitted when the object is created, the default value specified in the parameter list is used automatically.
Contents of Sale.h (Version 2)
#ifndef SALE_H
#define SALE_H
class Sale
{
private:
double itemCost;
double taxRate;
public:
Sale(double cost, double rate = 0.05)
{ itemCost = cost;
taxRate = rate; }
double getItemCost() const
{ return itemCost; }
double getTaxRate() const
{ return taxRate; }
double getTax() const
{ return (itemCost * taxRate); }
double getTotal() const
{ return (itemCost + getTax()); }
};
#endif🗊 Program 13-10
#include <iostream>
#include <iomanip>
#include "Sale.h"
using namespace std;
int main()
{
double cost;
cout << "Enter the cost of the item: ";
cin >> cost;
Sale itemSale(cost);
cout << fixed << showpoint << setprecision(2);
cout << "The amount of sales tax is $"
<< itemSale.getTax() << endl;
cout << "The total of the sale is $";
cout << itemSale.getTotal() << endl;
return 0;
}💻 Program Output
More about the Default Constructor
- If a constructor has default arguments for all of its parameters, it also serves as the default constructor because it can be called with no arguments.
Sale(double cost = 0.0, double rate = 0.05)
{ itemCost = cost;
taxRate = rate; }Classes with No Default Constructor
If all of a class’s constructors require arguments, then the class has no default constructor.
In this case, you must provide the required arguments whenever you create an object of that class, or a compiler error will occur.
13.9 Destructors
Concept:
- A destructor is a member function that is automatically called when an object is destroyed.
A destructor is a member function that has the same name as the class, preceded by a tilde (
~). For example,~Rectangle.Destructors are automatically called when an object goes out of scope or is explicitly deleted.
They are used to perform cleanup tasks, such as freeing memory that was dynamically allocated by the object.
Key characteristics of a destructor:
- It has the same name as the class, prefixed with
~. - It has no return type.
- It cannot accept arguments and therefore has no parameter list.
- It has the same name as the class, prefixed with
🗊 Program 13-11
#include <iostream>
using namespace std;
class Demo
{
public:
Demo();
~Demo();
};
Demo::Demo()
{
cout << "Welcome to the constructor!\n";
}
Demo::~Demo()
{
cout << "The destructor is now running.\n";
}
int main()
{
Demo demoObject;
cout << "This program demonstrates an object\n";
cout << "with a constructor and destructor.\n";
return 0;
}💻 Program Output
- The following
ContactInfoclass provides a practical example where the constructor allocates memory and the destructor frees it.
Contents of ContactInfo.h (Version 1)
#ifndef CONTACTINFO_H
#define CONTACTINFO_H
#include <cstring>
class ContactInfo
{
private:
char *name;
char *phone;
public:
ContactInfo(char *n, char *p)
{
name = new char[strlen(n) + 1];
phone = new char[strlen(p) + 1];
strcpy(name, n);
strcpy(phone, p); }
~ContactInfo()
{ delete [] name;
delete [] phone; }
const char *getName() const
{ return name; }
const char *getPhoneNumber() const
{ return phone; }
};
#endif🗊 Program 13-12
💻 Program Output
Destructors and Dynamically Allocated Class Objects
- When an object that was dynamically allocated with
newis destroyed using thedeleteoperator, its destructor is automatically called.
ContactInfo *objectPtr = new ContactInfo("Kristen Lee", "555-2021");
delete objectPtr; - If you use a smart pointer like
unique_ptr,deleteis not necessary; the object is destroyed and the destructor is called automatically when the smart pointer goes out of scope.
Checkpoint
13.12 Briefly describe the purpose of a constructor.
13.13 Briefly describe the purpose of a destructor.
13.14 A member function that is never declared with a return data type, but that may have arguments is which of the following?
The constructor
The destructor
Both the constructor and the destructor
Neither the constructor nor the destructor
13.15 A member function that is never declared with a return data type and can never have arguments is which of the following?
The constructor
The destructor
Both the constructor and the destructor
Neither the constructor nor the destructor
13.16 Destructor function names always start with ____________________.
A number
Tilde character (
~)A data type name
None of the above
13.17 A constructor that requires no arguments is called ____________________.
A default constructor
An overloaded constructor
A null constructor
None of the above
13.18 True or False: Constructors are never declared with a return data type.
13.19 True or False: Destructors are never declared with a return type.
13.20 True or False: Destructors may take any number of arguments.
13.10 Overloading Constructors
Concept:
- A class can have multiple constructors, a feature known as overloading.
Like regular functions, constructors can be overloaded. This means a class can have more than one constructor, as long as each has a different parameter list.
Overloading allows you to create objects in various ways. For example, you might have one constructor to create a default object and another to create an object with specific initial values.
The
InventoryItemclass below has three overloaded constructors.
Contents of InventoryItem.h
#ifndef INVENTORYITEM_H
#define INVENTORYITEM_H
#include <string>
using namespace std;
class InventoryItem
{
private:
string description;
double cost;
int units;
public:
InventoryItem()
{
description = "";
cost = 0.0;
units = 0; }
InventoryItem(string desc)
{
description = desc;
cost = 0.0;
units = 0; }
InventoryItem(string desc, double c, int u)
{
description = desc;
cost = c;
units = u; }
void setDescription(string d)
{ description = d; }
void setCost(double c)
{ cost = c; }
void setUnits(int u)
{ units = u; }
string getDescription() const
{ return description; }
double getCost() const
{ return cost; }
int getUnits() const
{ return units; }
};
#endif🗊 Program 13-13
#include <iostream>
#include <iomanip>
#include "InventoryItem.h"
int main()
{
InventoryItem item1;
item1.setDescription("Hammer");
item1.setCost(6.95);
item1.setUnits(12);
InventoryItem item2("Pliers");
InventoryItem item3("Wrench", 8.75, 20);
cout << "The following items are in inventory:\n";
cout << setprecision(2) << fixed << showpoint;
cout << "Description: " << item1.getDescription() << endl;
cout << "Cost: $" << item1.getCost() << endl;
cout << "Units on Hand: " << item1.getUnits() << endl << endl;
cout << "Description: " << item2.getDescription() << endl;
cout << "Cost: $" << item2.getCost() << endl;
cout << "Units on Hand: " << item2.getUnits() << endl << endl;
cout << "Description: " << item3.getDescription() << endl;
cout << "Cost: $" << item3.getCost() << endl;
cout << "Units on Hand: " << item3.getUnits() << endl;
return 0;
}💻 Program Output
Constructor Delegation
In C++ 11 and later, one constructor can call another constructor in the same class. This is known as constructor delegation.
This feature is useful for reducing redundant code when multiple constructors share common initialization logic.
The default constructor for the
Contactclass below delegates its work to the parameterized constructor by calling it with empty strings.
class Contact
{
private:
string name;
string email;
string phone;
public:
Contact() : Contact("", "", "")
{ }
Contact(string n, string e, string p)
{ name = n;
email = e;
phone = p;
}
};Only One Default Constructor and One Destructor
A class may have only one default constructor. This is because the compiler needs to know which constructor to call when an object is defined without any arguments.
Similarly, a class may have only one destructor. Since destructors do not take arguments, the compiler would have no way to distinguish between them if more than one existed.
Other Overloaded Member Functions
Other member functions, not just constructors, can also be overloaded.
This allows you to provide multiple ways to perform the same operation. For instance, a
setCostfunction could be overloaded to accept adoubleor astring.
void setCost(double c)
{ cost = c; }
void setCost(string c)
{ cost = stod(c); }13.11 Private Member Functions
Concept:
- A private member function can only be called from another member function of the same class.
Sometimes, a class requires helper functions for its own internal operations that should not be accessible to code outside the class.
Such functions should be declared as
private.This prevents them from being called at the wrong time or in the wrong context, which helps maintain the integrity of the object’s state.
In the example below, the
ContactInfoclass uses the private functionsinitNameandinitPhoneto modularize the logic within its constructor. These functions are private because they should only be called by the constructor.
Contents of ContactInfo.h (Version 2)
#ifndef CONTACTINFO_H
#define CONTACTINFO_H
#include <cstring>
class ContactInfo
{
private:
char *name;
char *phone;
void initName(char *n)
{ name = new char[strlen(n) + 1];
strcpy(name, n); }
void initPhone(char *p)
{ phone = new char[strlen(p) + 1];
strcpy(phone, p); }
public:
ContactInfo(char *n, char *p)
{
initName(n);
initPhone(n); }
~ContactInfo()
{ delete [] name;
delete [] phone; }
const char *getName() const
{ return name; }
const char *getPhoneNumber() const
{ return phone; }
};
#endif13.12 Arrays of Objects
Concept:
- You can define and use arrays whose elements are class objects.
Just like with any other data type, you can create arrays of class objects.
To define an array of objects, use the same syntax as for other array types. The default constructor will be called for each object in the array.
const int ARRAY_SIZE = 40;
InventoryItem inventory[ARRAY_SIZE];To call a constructor that requires arguments for objects in an array, you must provide an initializer list.
For a constructor with one argument, the list can be simple:
InventoryItem inventory[] = {"Hammer", "Wrench", "Pliers"};- For a constructor with multiple arguments, the initializer for each element must be in the form of a function call:
InventoryItem inventory[] = { InventoryItem("Hammer", 6.95, 12),
InventoryItem("Wrench", 8.75, 20),
InventoryItem("Pliers", 3.75, 10) };- It is not necessary to call the same constructor for every element in the array. You can mix and match initializers.
InventoryItem inventory[] = { "Hammer",
InventoryItem("Wrench", 8.75, 20),
"Pliers" };If you provide fewer initializers than the array size, the default constructor will be called for the remaining elements.
Key rules for using initializer lists with object arrays:
- If the class has no default constructor, you must provide an initializer for every object in the array.
- If the initializer list is shorter than the array, the default constructor is used for the rest of the objects.
- For multi-argument constructors, use the function-call syntax in the initializer list.
Accessing Members of Objects in an Array
- To access the members of an object in an array, use the subscript operator (
[]) to select the object, followed by the dot operator (.) to access the member.
inventory[2].setUnits(30);- The following program demonstrates creating and using an array of
InventoryItemobjects.
🗊 Program 13-14
#include <iostream>
#include <iomanip>
#include "InventoryItem.h"
using namespace std;
int main()
{
const int NUM_ITEMS = 5;
InventoryItem inventory[NUM_ITEMS] = {
InventoryItem("Hammer", 6.95, 12),
InventoryItem("Wrench", 8.75, 20),
InventoryItem("Pliers", 3.75, 10),
InventoryItem("Ratchet", 7.95, 14),
InventoryItem("Screwdriver", 2.50, 22) };
cout << setw(14) <<"Inventory Item"
<< setw(8) << "Cost" << setw(8)
<< setw(16) << "Units on Hand\n";
cout << "-------------------------------------\n";
for (int i = 0; i < NUM_ITEMS; i++)
{
cout << setw(14) << inventory[i].getDescription();
cout << setw(8) << inventory[i].getCost();
cout << setw(7) << inventory[i].getUnits() << endl;
}
return 0;
}💻 Program Output
Checkpoint
13.21 What will the following program display on the screen?
#include <iostream> using namespace std; class Tank { private: int gallons; public: Tank() { gallons = 50; } Tank(int gal) { gallons = gal; } int getGallons() { return gallons; } }; int main() { Tank storage[3] = { 10, 20 }; for (int index = 0; index < 3; index++) cout << storage[index].getGallons() << endl; return 0; }13.22 What will the following program display on the screen?
#include <iostream> using namespace std; class Package { private: int value; public: Package() { value = 7; cout << value << endl; } Package(int v) { value = v; cout << value << endl; } ~Package() { cout << value << endl; } }; int main() { Package obj1(4); Package obj2; Package obj3(2); return 0; }13.23 In your answer for Checkpoint 13.22, indicate for each line of output whether the line is displayed by constructor https://www.google.com/search?q=%231, constructor https://www.google.com/search?q=%232, or the destructor.
13.24 Why would a member function be declared private?
13.25 Define an array of three
InventoryItemobjects.13.26 Complete the following program so it defines an array of
Yardobjects. The program should use a loop to ask the user for the length and width of eachYard.#include <iostream> using namespace std; class Yard { private: int length, width; public: Yard() { length = 0; width = 0; } setLength(int len) { length = len; } setWidth(int w) { width = w; } }; int main() { }
13.13 Focus on Problem Solving and Program Design: An OOP Case Study
This case study involves developing a class to model a bank account.
The class should be able to:
- Store the account balance and number of transactions.
- Handle deposits and withdrawals.
- Calculate and add interest.
- Report the balance, transaction count, and interest earned.
Private Member Variables
Table 13-4 lists the private member variables needed by the class.
| Variable | Description |
|---|---|
balance |
A double that holds the current account balance. |
interestRate |
A double that holds the interest rate for the period. |
interest |
A double that holds the interest earned for the current period. |
transactions |
An integer that holds the current number of transactions. |
Public Member Functions
Table 13-5 lists the public member functions needed by the class.
| Function | Description |
|---|---|
| Constructor | Takes arguments to be initially stored in the balance and interestRate members. The default value for the balance is zero, and the default value for the interest rate is 0.045. |
setInterestRate |
Takes a double argument, which is stored in the interestRate member. |
makeDeposit |
Takes a double argument, which is the amount of the deposit. This argument is added to balance. |
withdraw |
Takes a double argument, which is the amount of the withdrawal. This value is subtracted from the balance, unless the withdrawal amount is greater than the balance. If this happens, the function reports an error. |
calcInterest |
Takes no arguments. This function calculates the amount of interest for the current period, stores this value in the interest member, then adds it to the balance member. |
getInterestRate |
Returns the current interest rate (stored in the interestRate member). |
getBalance |
Returns the current balance (stored in the balance member). |
getInterest |
Returns the interest earned for the current period (stored in the interest member). |
getTransactions |
Returns the number of transactions for the current period (stored in the transactions member). |
The Class Declaration
- The following code shows the declaration for the
Accountclass.
Contents of Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
private:
double balance;
double interestRate;
double interest;
int transactions;
public:
Account(double iRate = 0.045, double bal = 0)
{ balance = bal;
interestRate = iRate;
interest = 0;
transactions = 0; }
void setInterestRate(double iRate)
{ interestRate = iRate; }
void makeDeposit(double amount)
{ balance += amount; transactions++; }
void withdraw(double amount);
void calcInterest()
{ interest = balance * interestRate; balance += interest; }
double getInterestRate() const
{ return interestRate; }
double getBalance() const
{ return balance; }
double getInterest() const
{ return interest; }
int getTransactions() const
{ return transactions; }
};
#endifThe withdraw Member Function
- The
withdrawfunction is defined externally. It checks for sufficient funds before processing the withdrawal and returnstrueorfalseto indicate success.
Contents of Account.cpp
The Class’s Interface
The member variables are
privateto protect the integrity of the account data.If they were public, errors could occur, such as:
- A withdrawal for more than the current balance.
- A deposit or withdrawal that doesn’t update the transaction count.
- Incorrect interest calculations.
The public member functions provide a safe and controlled interface for manipulating the account.
Implementing the Class
- The following program provides a menu-driven interface to test and use the
Accountclass.
🗊 Program 13-15
#include <iostream>
#include <cctype>
#include <iomanip>
#include "Account.h"
using namespace std;
void displayMenu();
void makeDeposit(Account &);
void withdraw(Account &);
int main()
{
Account savings;
char choice;
cout << fixed << showpoint << setprecision(2);
do
{
displayMenu();
cin >> choice;
while (toupper(choice) < 'A' || toupper(choice) > 'G')
{
cout << "Please make a choice in the range "
<< "of A through G:";
cin >> choice;
}
switch(choice)
{
case 'a':
case 'A': cout << "The current balance is $";
cout << savings.getBalance() << endl;
break;
case 'b':
case 'B': cout << "There have been ";
cout << savings.getTransactions()
<< " transactions.\n";
break;
case 'c':
case 'C': cout << "Interest earned for this period: $";
cout << savings.getInterest() << endl;
break;
case 'd':
case 'D': makeDeposit(savings);
break;
case 'e':
case 'E': withdraw(savings);
break;
case 'f':
case 'F': savings.calcInterest();
cout << "Interest added.\n";
}
} while (toupper(choice) != 'G');
return 0;
}
void displayMenu()
{
cout << "\n MENU\n";
cout << "-----------------------------------------\n";
cout << "A) Display the account balance\n";
cout << "B) Display the number of transactions\n";
cout << "C) Display interest earned for this period\n";
cout << "D) Make a deposit\n";
cout << "E) Make a withdrawal\n";
cout << "F) Add interest for this period\n";
cout << "G) Exit the program\n\n";
cout << "Enter your choice: ";
}
void makeDeposit(Account &acnt)
{
double dollars;
cout << "Enter the amount of the deposit: ";
cin >> dollars;
cin.ignore();
acnt.makeDeposit(dollars);
}
void withdraw(Account &acnt)
{
double dollars;
cout << "Enter the amount of the withdrawal: ";
cin >> dollars;
cin.ignore();
if (!acnt.withdraw(dollars))
cout << "ERROR: Withdrawal amount too large.\n\n";
}💻 Program Output
13.14 Focus on Object-Oriented Programming: Simulating Dice with Objects
- This section demonstrates how to create a
Dieclass to simulate the rolling of dice with a variable number of sides.
Contents of Die.h
Contents of Die.cpp
#include <cstdlib>
#include <ctime>
#include "Die.h"
using namespace std;
Die::Die(int numSides)
{
unsigned seed = time(0);
srand(seed);
sides = numSides;
roll();
}
void Die::roll()
{
const int MIN_VALUE = 1;
value = (rand() % (sides - MIN_VALUE + 1)) + MIN_VALUE;
}
int Die::getSides()
{
return sides;
}
int Die::getValue()
{
return value;
}Synopsis of Class Members:
sides: Anintto hold the number of sides on the die.value: Anintto hold the current face value of the die.- Constructor: Accepts the number of sides (defaulting to 6), seeds the random number generator, sets the number of sides, and performs an initial roll.
roll(): Simulates a die roll by generating a random number between 1 and the number of sides.getSides(): Returns the number of sides.getValue(): Returns the current value.
The following program demonstrates creating two
Dieobjects with different numbers of sides and rolling them multiple times.
🗊 Program 13-16
#include <iostream>
#include "Die.h"
using namespace std;
int main()
{
const int DIE1_SIDES = 6;
const int DIE2_SIDES = 12;
const int MAX_ROLLS = 5;
Die die1(DIE1_SIDES);
Die die2(DIE2_SIDES);
cout << "This simulates the rolling of a "
<< die1.getSides() << " sided die and a "
<< die2.getSides() << " sided die.\n";
cout << "Initial value of the dice:\n";
cout << die1.getValue() << " "
<< die2.getValue() << endl;
cout << "Rolling the dice " << MAX_ROLLS
<< " times.\n";
for (int count = 0; count < MAX_ROLLS; count++)
{
die1.roll();
die2.roll();
cout << die1.getValue() << " "
<< die2.getValue() << endl;
}
return 0;
}💻 Program Output
13.15 Focus on Object-Oriented Design: The Unified Modeling Language (UML)
Concept:
- The Unified Modeling Language (UML) offers a standard graphical notation for designing and depicting object-oriented systems.
A UML diagram is a helpful tool for designing a class.
The general layout is a box divided into three sections:
- Top Section: Class Name
- Middle Section: Member Variables (Attributes)
- Bottom Section: Member Functions (Operations)
Showing Access Specification in UML Diagrams
- UML uses specific characters to indicate member access specification:
-(minus sign) indicates a private member.+(plus sign) indicates a public member.
Data Type and Parameter Notation in UML Diagrams
- UML provides notation to specify data types. The syntax is
memberName : dataType, which is the reverse of C++ syntax.- Member Variable:
- width : double - Function Return Type:
+ getLength() : double - Function Parameters:
+ setLength(len : double) : void
- Member Variable:
Showing Constructors and Destructors in a UML Diagram
Constructors are shown like other functions but without a return type.
The UML diagram in Figure 13-22 shows the design for an
InventoryItemclass, including overloaded constructors and member data types.
13.16 Focus on Object-Oriented Design: Finding the Classes and Their Responsibilities
Concept:
- A primary step in creating an OO application is to identify the necessary classes and determine what each class is responsible for.
Finding the Classes
The first step in designing an OO application is to identify the classes needed to model the real-world objects in the problem.
A simple technique for finding classes involves these steps:
- Write a detailed description of the problem domain (the set of real-world objects and events related to the problem).
- Identify all the nouns in the description. Each noun is a potential class.
- Refine the list of nouns to keep only the classes that are relevant to the problem.
Identify All of the Nouns
- After writing the problem domain description, list every noun and noun phrase. This list becomes the initial set of candidate classes.
Refine the List of Nouns
- Not every noun will become a class. Refine the list by eliminating nouns based on the following criteria:
- Redundancy: Remove nouns that refer to the same concept (e.g., “car” and “foreign car” might both just be a
Carclass). - Irrelevance: Remove nouns that represent items not essential to solving the specific problem (e.g., a “manager” class might be unnecessary if the application only generates quotes and doesn’t track who created them).
- Objects vs. Classes: Remove nouns that represent specific instances (objects) rather than a general category (class). For example, “Porsche” is an object of the
Carclass. - Simple Values: Remove nouns that represent simple data types (like
intorstring) that can be stored as attributes within another class, rather than needing a class of their own (e.g., “name”, “address”, “year”).
- Redundancy: Remove nouns that refer to the same concept (e.g., “car” and “foreign car” might both just be a
Identifying a Class’s Responsibilities
Once classes are identified, determine their responsibilities. A class’s responsibilities are:
- Things the class needs to know: These become the class’s attributes (member variables).
- Actions the class needs to do: These become the class’s member functions.
To find these responsibilities, analyze the problem domain description and ask: “What must this class know?” and “What must this class do?”
For example, after analyzing the “Joe’s Automotive Shop” problem, we might identify three classes:
Customer,Car, andServiceQuote.- The
Customerclass is responsible for knowing a name, address, and phone number, and for doing things like setting and getting that information. - The
Carclass is responsible for knowing a make, model, and year. - The
ServiceQuoteclass is responsible for knowing parts and labor charges and for doing calculations for sales tax and the total cost.
- The
This Is Only the Beginning
Object-oriented design is an iterative process.
Your initial list of classes and responsibilities is a starting point. As your understanding of the problem deepens, you will likely refine and improve your design.
Checkpoint
13.27 What is a problem domain?
13.28 When designing an object-oriented application, who should write a description of the problem domain?
13.29 How do you identify the potential classes in a problem domain description?
13.30 What are a class’s responsibilities?
13.31 What two questions should you ask to determine a class’s responsibilities?
13.32 Will all of a class’s actions always be directly mentioned in the problem domain description?
13.33 Look at the following description of a problem domain:
A doctor sees patients in her practice. When a patient comes to the practice, the doctor performs one or more procedures on the patient. Each procedure that the doctor performs has a description and a standard fee. As the patient leaves the practice, he or she receives a statement from the office manager. The statement shows the patient’s name and address, as well as the procedures that were performed, and the total charge for the procedures.
Assume you are writing an application to generate a statement that can be printed and given to the patient.
Identify all of the potential classes in this problem domain.
Refine the list to include only the necessary class or classes for this problem.
Identify the responsibilities of the class or classes that you identified in step B.
Review Questions and Exercises
Short Answer
What is the difference between a class and an instance of the class?
What is the difference between the following
Personstructure andPersonclass?struct Person { string name; int age; }; class Person { string name; int age; };What is the default access specification of class members?
Look at the following function header for a member function:
void Circle::getRadius()What is the name of the function?
Of, what class is the function a member?
A contractor uses a blueprint to build a set of identical houses. Are classes analogous to the blueprint or the houses?
What is a mutator function? What is an accessor function?
Is it a good idea to make member variables private? Why or why not?
Can you think of a good reason to avoid writing statements in a class member function that use
coutorcin?Under what circumstances should a member function be private?
What is a constructor? What is a destructor?
What is a default constructor? Is it possible to have more than one default constructor?
Is it possible to have more than one constructor? Is it possible to have more than one destructor?
If a class object is dynamically allocated in memory, does its constructor execute? If so, when?
When defining an array of class objects, how do you pass arguments to the constructor for each object in the array?
What are a class’s responsibilities?
How do you identify the classes in a problem domain description?
Fill-in-the-Blank
The two common programming methods in practice today are ____________________ and ____________________.
____________________ programming is centered around functions or procedures.
____________________ programming is centered around objects.
____________________ is an object’s ability to contain and manipulate its own data.
In C++, the ____________________ is the construct primarily used to create objects.
A class is very similar to a(n) ____________________.
A(n) ____________________ is a key word inside a class declaration that establishes a member’s accessibility.
The default access specification of class members is ____________________.
The default access specification of a
structin C++ is ____________________.Defining a class object is often called the ____________________ of a class.
Members of a class object may be accessed through a pointer to the object by using the ____________________ operator.
If you were writing the declaration of a class named
Canine, what would you name the file it was stored in? ____________________If you were writing the external definitions of the
Canineclass’s member functions, you would save them in a file named ____________________.When a member function’s body is written inside a class declaration, the function is ____________________.
A(n) ____________________ is automatically called when an object is created.
A(n) ____________________ is a member function with the same name as the class.
____________________ are useful for performing initialization or setup routines in a class object.
Constructors cannot have a(n) ____________________ type.
A(n) ____________________ constructor is one that requires no arguments.
A(n) ____________________ is a member function that is automatically called when an object is destroyed.
A destructor has the same name as the class, but is preceded by a(n) ____________________ character.
Like constructors, destructors cannot have a(n) ____________________ type.
A constructor whose arguments all have default values is a(n) ____________________ constructor.
A class may have more than one constructor, as long as each has a different ____________________.
A class may only have one default ____________________ and one ____________________.
A(n) ____________________ may be used to pass arguments to the constructors of elements in an object array.
Algorithm Workbench
Write a class declaration named
Circlewith a private member variable namedradius. Write set and get functions to access theradiusvariable, and a function namedgetAreathat returns the area of the circle. The area is calculated as3.14159 * radius * radiusAdd a default constructor to the
Circleclass in Question 43. The constructor should initialize theradiusmember to 0.Add an overloaded constructor to the
Circleclass in Question 44. The constructor should accept an argument and assign its value to theradiusmember variable.Write a statement that defines an array of five objects of the
Circleclass in Question 45. Let the default constructor execute for each element of the array.Write a statement that defines an array of five objects of the
Circleclass in Question 45. Pass the following arguments to the elements’ constructor: 12, 7, 9, 14, and 8.Write a
forloop that displays the radius and area of the circles represented by the array you defined in Question 47.If the items on the following list appeared in a problem domain description, which would be potential classes?
Animal Medication Nurse Inoculate Operate Advertise Doctor Invoice Measure Patient Client Customer Look at the following description of a problem domain:
The bank offers the following types of accounts to its customers: savings accounts, checking accounts, and money market accounts. Customers are allowed to deposit money into an account (thereby increasing its balance), withdraw money from an account (thereby decreasing its balance), and earn interest on the account. Each account has an interest rate.
Assume you are writing an application that will calculate the amount of interest earned for a bank account.
Identify the potential classes in this problem domain.
Refine the list to include only the necessary class or classes for this problem.
Identify the responsibilities of the class or classes.
True or False
T F Private members must be declared before public members.
T F Class members are private by default.
T F Members of a
structare private by default.T F Classes and structures in C++ are very similar.
T F All private members of a class must be declared together.
T F All public members of a class must be declared together.
T F It is legal to define a pointer to a class object.
T F You can use the
newoperator to dynamically allocate an instance of a class.T F A private member function may be called from a statement outside the class, as long as the statement is in the same program as the class declaration.
T F Constructors do not have to have the same name as the class.
T F Constructors may not have a return type.
T F Constructors cannot take arguments.
T F Destructors cannot take arguments.
T F Destructors may return a value.
T F Constructors may have default arguments.
T F Member functions may be overloaded.
T F Constructors may not be overloaded.
T F A class may not have a constructor with no parameter list, and a constructor whose arguments all have default values.
T F A class may only have one destructor.
T F When an array of objects is defined, the constructor is only called for the first element.
T F To find the classes needed for an object-oriented application, you identify all of the verbs in a description of the problem domain.
T F A class’s responsibilities are the things the class is responsible for knowing, and actions the class must perform.
Find the Errors
Each of the following class declarations or programs contain errors. Find as many as possible.
-
class Circle: { private double centerX; double centerY; double radius; public setCenter(double, double); setRadius(double); } -
#include <iostream> using namespace std; Class Moon; { Private; double earthWeight; double moonWeight; Public; moonWeight(double ew); { earthWeight = ew; moonWeight = earthWeight / 6; } double getMoonWeight(); { return moonWeight; } } int main() { double earth; cout >> "What is your weight? "; cin << earth; Moon lunar(earth); cout << "On the moon you would weigh " <<lunar.getMoonWeight() << endl; return 0; } -
#include <iostream> using namespace std; class DumbBell; { int weight; public: void setWeight(int); }; void setWeight(int w) { weight = w; } int main() { DumbBell bar; DumbBell(200); cout << "The weight is " << bar.weight << endl; return 0; } -
class Change { public: int pennies; int nickels; int dimes; int quarters; Change() { pennies = nickels = dimes = quarters = 0; } Change(int p = 100, int n = 50, d = 50, q = 25); }; void Change::Change(int p, int n, d, q) { pennies = p; nickels = n; dimes = d; quarters = q; }
Programming Challenges
Date
Design a class called
Date. The class should store a date in three integers:month,day, andyear. There should be member functions to print the date in the following forms:12/25/2018
December 25, 2018
25 December 2018
Demonstrate the class by writing a complete program implementing it.
Input Validation: Do not accept values for the day greater than 31 or less than 1. Do not accept values for the month greater than 12 or less than 1.

Solving the
EmployeeClass ProblemEmployeeClassWrite a class named
Employeethat has the following member variables:name—a string that holds the employee’s nameidNumber—a nintvariable that holds the employee’s ID numberdepartment—a string that holds the name of the department where the employee worksposition—a string that holds the employee’s job title
The class should have the following constructors:
A constructor that accepts the following values as arguments and assigns them to the appropriate member variables: employee’s name, employee’s ID number, department, and position.
A constructor that accepts the following values as arguments and assigns them to the appropriate member variables: employee’s name and ID number. The
departmentandpositionfields should be assigned an empty string ("").A default constructor that assigns empty strings (
"") to thename,department, andpositionmember variables, and 0 to theidNumbermember variable.
Write appropriate mutator functions that store values in these member variables and accessor functions that return the values in these member variables. Once you have written the class, write a separate program that creates three
Employeeobjects to hold the following data:Name ID Number Department Position Susan Meyers 47899 Accounting Vice President Mark Jones 39119 IT Programmer Joy Rogers 81774 Manufacturing Engineer The program should store this data in the three objects and then display the data for each employee on the screen.
CarClassWrite a class named
Carthat has the following member variables:yearModel—anintthat holds the car’s year modelmake—a string that holds the make of the carspeed—anintthat holds the car’s current speed
In addition, the class should have the following constructor and other member functions:
Constructor—The constructor should accept the car’s year model and make as arguments. These values should be assigned to the object’s
yearModelandmakemember variables. The constructor should also assign 0 to thespeedmember variables.Accessor—appropriate accessor functions to get the values stored in an object’s
yearModel,make, andspeedmember variablesaccelerate—Theacceleratefunction should add 5 to thespeedmember variable each time it is called.brake—Thebrakefunction should subtract 5 from thespeedmember variable each time it is called.
Demonstrate the class in a program that creates a
Carobject, then calls theacceleratefunction five times. After each call to theacceleratefunction, get the current speed of the car and display it. Then, call thebrakefunction five times. After each call to thebrakefunction, get the current speed of the car and display it.Patient Charges
Write a class named
Patientthat has member variables for the following data:First name, middle name, last name
Address, city, state, and ZIP code
Phone number
Name and phone number of emergency contact
The
Patientclass should have a constructor that accepts an argument for each member variable. ThePatientclass should also have accessor and mutator functions for each member variable.Next, write a class named
Procedurethat represents a medical procedure that has been performed on a patient. TheProcedureclass should have member variables for the following data:Name of the procedure
Date of the procedure
Name of the practitioner who performed the procedure
Charges for the procedure
The
Procedureclass should have a constructor that accepts an argument for each member variable. TheProcedureclass should also have accessor and mutator functions for each member variable.Next, write a program that creates an instance of the
Patientclass, initialized with sample data. Then, create three instances of theProcedureclass, initialized with the following data:Procedure #1: Procedure #2: Procedure #3: Procedure name: Physical Exam
Date: Today’s date
Practitioner: Dr. Irvine
Charge: 250.00
Procedure name: X-ray
Date: Today’s date
Practitioner: Dr. Jamison
Charge: 500.00
Procedure name: Blood test
Date: Today’s date
Practitioner: Dr. Smith
Charge: 200.00
The program should display the patient’s information, information about all three of the procedures, and the total charges of the three procedures.
RetailItemClassWrite a class named
RetailItemthat holds data about an item in a retail store. The class should have the following member variables:description—a string that holds a brief description of the itemunitsOnHand—anintthat holds the number of units currently in inventoryprice—adoublethat holds the item’s retail price
Write a constructor that accepts arguments for each member variable, appropriate mutator functions that store values in these member variables, and accessor functions that return the values in these member variables. Once you have written the class, write a separate program that creates three
RetailItemobjects and stores the following data in them:Description Units On Hand Price Item #1 Jacket 12 59.95 Item #2 Designer Jeans 40 34.95 Item #3 Shirt 20 24.95 Inventory Class
Design an
Inventoryclass that can hold information and calculate data for items in a retail store’s inventory. The class should have the following private member variables:Variable Name Description itemNumberAn intthat holds the item’s item number.quantityAn intfor holding the quantity of the items on hand.costA doublefor holding the wholesale per-unit cost of the itemtotalCostA doublefor holding the total inventory cost of the item (calculated asquantitytimescost).The class should have the following public member functions:
Member Function Description Default Constructor Sets all the member variables to 0. Constructor #2 Accepts an item’s number, cost, and quantity as arguments. The function should copy these values to the appropriate member variables and then call the setTotalCostfunction.setItemNumberAccepts an integer argument that is copied to the itemNumbermember variable.setQuantityAccepts an integer argument that is copied to the quantitymember variable.setCostAccepts a doubleargument that is copied to thecostmember variable.setTotalCostCalculates the total inventory cost for the item ( quantitytimescost) and stores the result intotalCost.getItemNumberReturns the value in itemNumber.getQuantityReturns the value in quantity.getCostReturns the value in cost.getTotalCostReturns the value in totalCost.Demonstrate the class in a driver program.
Input Validation: Do not accept negative values for item number, quantity, or cost.
TestScoresClassDesign a
TestScoresclass that has member variables to hold three test scores. The class should have a constructor, accessor, and mutator functions for the test score fields and a member function that returns the average of the test scores. Demonstrate the class by writing a separate program that creates an instance of the class. The program should ask the user to enter three test scores, which are stored in theTestScoresobject. Then the program should display the average of the scores, as reported by theTestScoresobject.Circle Class
Write a
Circleclass that has the following member variables:radius—adoublepi—adoubleinitialized with the value 3.14159
The class should have the following member functions:
Default Constructor—a default constructor that sets
radiusto 0.0Constructor—accepts the radius of the circle as an argument
setRadius—a mutator function for the radius variablegetRadius—an accessor function for the radius variablegetArea—returns the area of the circle, which is calculated asarea = pi * radius * radiusgetDiameter—returns the diameter of the circle, which is calculated asdiameter = radius * 2getCircumference—returns the circumference of the circle, which is calculated ascircumference = 2 * pi * radius
Write a program that demonstrates the
Circleclass by asking the user for the circle’s radius, creating aCircleobject, then reporting the circle’s area, diameter, and circumference.Population
In a population, the birth rate and death rate are calculated as follows:
\begin{array}{l} {\text{Birth}\,\text{Rate}\, = \,\text{Number}\,\text{of}\,\text{Births}\, \div \,\text{Population}} \\ {\text{Death}\,\text{Rate}\, = \,\text{Number}\,\text{of}\,\text{Deaths}\, \div \,\text{Population}} \end{array}
For example, in a population of 100,000 that has 8,000 births and 6,000 deaths per year, the birth rate and death rate are:
\begin{array}{l} {\text{Birth}\,\text{Rate}\, = \,\text{8,000}\, \div \,\text{100,000}\, = \,\text{0}\text{.08}} \\ {\text{Death}\,\text{Rate}\, = \,\text{6,000}\, \div \,\text{100,000}\, = \,\text{0}\text{.06}} \end{array}
Design a
Populationclass that stores a population, number of births, and number of deaths for a period of time. Member functions should return the birth rate and death rate. Implement the class in a program.Input Validation: Do not accept population figures less than 1, or birth or death numbers less than 0.
Number Array Class
Design a class that has an array of floating-point numbers. The constructor should accept an integer argument and dynamically allocate the array to hold that many numbers. The destructor should free the memory held by the array. In addition, there should be member functions to perform the following operations:
Store a number in any element of the array
Retrieve a number from any element of the array
Return the highest value stored in the array
Return the lowest value stored in the array
Return the average of all the numbers stored in the array
Demonstrate the class in a program.
Payroll Class
Design a
PayRollclass that has data members for an employee’s hourly pay rate, number of hours worked, and total pay for the week. Write a program with an array of sevenPayRollobjects. The program should ask the user for the number of hours each employee has worked, and will then display the amount of gross pay each has earned.Input Validation: Do not accept values greater than 60 for the number of hours worked.
Coin Toss Simulator
Write a class named
Coin. TheCoinclass should have the following member variable:- A
stringnamedsideUp. ThesideUpmember variable will hold either “heads” or “tails” indicating the side of the coin that is facing up.
The
Coinclass should have the following member functions:A default constructor that randomly determines the side of the coin that is facing up (“heads” or “tails”) and initializes the
sideUpmember variable accordingly.A
voidmember function namedtossthat simulates the tossing of the coin. When thetossmember function is called, it randomly determines the side of the coin that is facing up (“heads” or “tails”) and sets thesideUpmember variable accordingly.A member function named
getSideUpthat returns the value of thesideUpmember variable.
Write a program that demonstrates the
Coinclass. The program should create an instance of the class and display the side that is initially facing up. Then, use a loop to toss the coin 20 times. Each time the coin is tossed, display the side that is facing up. The program should keep count of the number of times heads is facing up and the number of times tails is facing up, and display those values after the loop finishes.- A
Tossing Coins for a Dollar
For this assignment, you will create a game program using the
Coinclass from Programming Challenge 12 (Coin Toss Simulator). The program should have three instances of theCoinclass: one representing a quarter, one representing a dime, and one representing a nickel.When the game begins, your starting balance is $0. During each round of the game, the program will toss the simulated coins. When a coin is tossed, the value of the coin is added to your balance if it lands heads-up. For example, if the quarter lands heads-up, 25 cents is added to your balance. Nothing is added to your balance for coins that land tails-up. The game is over when your balance reaches $1 or more. If your balance is exactly $1, you win the game. You lose if your balance exceeds $1.
Fishing Game Simulation
For this assignment, you will write a program that simulates a fishing game. In this game, a six-sided die is rolled to determine what the user has caught. Each possible item is worth a certain number of fishing points. The points will not be displayed until the user has finished fishing, then a message is displayed congratulating the user depending on the number of fishing points gained.
Here are some suggestions for the game’s design:
Each round of the game is performed as an iteration of a loop that repeats as long as the player wants to fish for more items.
At the beginning of each round, the program will ask the user whether he or she wants to continue fishing.
The program simulates the rolling of a six-sided die (use the
Dieclass that was demonstrated in this chapter).Each item that can be caught is represented by a number generated from the die. For example, 1 for “a huge fish,” 2 for “an old shoe,” 3 for “a little fish,” and so on.
Each item the user catches is worth a different amount of points.
The loop keeps a running total of the user’s fishing points.
After the loop has finished, the total number of fishing points is displayed, along with a message that varies depending on the number of points earned.
Mortgage Payment
Design a class that will determine the monthly payment on a home mortgage. The monthly payment with interest compounded monthly can be calculated as follows:
\text{Payment} = \frac{\text{Loan} \times \frac{\text{Rate}}{12} \times \text{Term}}{\text{Term} - 1}
where
\text{Term} = \left( {1 + \frac{\text{Rate}}{12}} \right)^{12 \times \text{Years}}
Payment = the monthly payment
Loan = the dollar amount of the loan
Rate = the annual interest rate
Years = the number of years of the loan
The class should have member functions for setting the loan amount, interest rate, and number of years of the loan. It should also have member functions for returning the monthly payment amount and the total amount paid to the bank at the end of the loan period. Implement the class in a complete program.
Input Validation: Do not accept negative numbers for any of the loan values.
Freezing and Boiling Points
The following table lists the freezing and boiling points of several substances.
Substance Freezing Point Boiling Point Ethyl alcohol -173 172 Oxygen -362 -306 Water 32 212 Design a class that stores a temperature in a
temperaturemember variable and has the appropriate accessor and mutator functions. In addition to appropriate constructors, the class should have the following member functions:isEthylFreezing—This function should return theboolvaluetrueif the temperature stored in thetemperaturefield is at or below the freezing point of ethyl alcohol. Otherwise, the function should returnfalse.isEthylBoiling—This function should return theboolvaluetrueif the temperature stored in thetemperaturefield is at or above the boiling point of ethyl alcohol. Otherwise, the function should returnfalse.isOxygenFreezing—This function should return theboolvaluetrueif the temperature stored in thetemperaturefield is at or below the freezing point of oxygen. Otherwise, the function should returnfalse.isOxygenBoiling—This function should return theboolvaluetrueif the temperature stored in thetemperaturefield is at or above the boiling point of oxygen. Otherwise, the function should returnfalse.isWaterFreezing—This function should return theboolvaluetrueif the temperature stored in thetemperaturefield is at or below the freezing point of water. Otherwise, the function should returnfalse.isWaterBoiling—This function should return theboolvaluetrueif the temperature stored in thetemperaturefield is at or above the boiling point of water. Otherwise, the function should returnfalse.
Write a program that demonstrates the class. The program should ask the user to enter a temperature, then display a list of the substances that will freeze at that temperature, and those that will boil at that temperature. For example, if the temperature is -20 the class should report that water will freeze and oxygen will boil at that temperature.
Cash Register
Design a
CashRegisterclass that can be used with theInventoryItemclass discussed in this chapter. TheCashRegisterclass should perform the following:Ask the user for the item and quantity being purchased.
Get the item’s cost from the
InventoryItemobject.Add a 30 percent profit to the cost to get the item’s unit price.
Multiply the unit price times the quantity being purchased to get the purchase subtotal.
Compute a 6 percent sales tax on the subtotal to get the purchase total.
Display the purchase subtotal, tax, and total on the screen.
Subtract the quantity being purchased from the
onHandvariable of theInventoryItemclass object.
Implement both classes in a complete program. Feel free to modify the
InventoryItemclass in any way necessary.Input Validation: Do not accept a negative value for the quantity of items being purchased.
A Game of 21
For this assignment, you will write a program that lets the user play against the computer in a variation of the popular blackjack card game. In this variation of the game, two six-sided dice are used instead of cards. The dice are rolled, and the player tries to beat the computer’s hidden total without going over 21.
Here are some suggestions for the game’s design:
Each round of the game is performed as an iteration of a loop that repeats as long as the player agrees to roll the dice, and the player’s total does not exceed 21.
At the beginning of each round, the program will ask the users whether they want to roll the dice to accumulate points.
During each round, the program simulates the rolling of two six-sided dice. It rolls the dice first for the computer, then it asks the user if he or she wants to roll. (Use the
Dieclass demonstrated in this chapter to simulate the dice).The loop keeps a running total of both the computer and the user’s points.
The computer’s total should remain hidden until the loop has finished.
After the loop has finished, the computer’s total is revealed, and the player with the most points without going over 21 wins.
Trivia Game
In this programming challenge, you will create a simple trivia game for two players. The program will work like this:
Starting with player 1, each player gets a turn at answering five trivia questions. (There are a total of 10 questions.) When a question is displayed, four possible answers are also displayed. Only one of the answers is correct, and if the player selects the correct answer, he or she earns a point.
After answers have been selected for all of the questions, the program displays the number of points earned by each player and declares the player with the highest number of points the winner.
In this program, you will design a
Questionclass to hold the data for a trivia question. TheQuestionclass should have member variables for the following data:A trivia question
Possible answer #1
Possible answer #2
Possible answer #3
Possible answer #4
The number of the correct answer (1, 2, 3, or 4)
The
Questionclass should have appropriate constructor(s), accessor, and mutator functions.The program should create an array of 10
Questionobjects, one for each trivia question. Make up your own trivia questions on the subject or subjects of your choice for the objects.
Group Project
Patient Fees
This program should be designed and written by a team of students. Here are some suggestions:
One or more students may work on a single class.
The requirements of the program should be analyzed so that each student is given about the same workload.
The parameters and return types of each function and class member function should be decided in advance.
The program will be best implemented as a multi-file program.
You are to write a program that computes a patient’s bill for a hospital stay. The different components of the program are
The
PatientAccountclassThe
SurgeryclassThe
PharmacyclassThe
mainprogramThe
PatientAccountclass will keep a total of the patient’s charges. It will also keep track of the number of days spent in the hospital. The group must decide on the hospital’s daily rate.The
Surgeryclass will have stored within it the charges for at least five types of surgery. It can update the charges variable of thePatientAccountclass.The
Pharmacyclass will have stored within it the price of at least five types of medication. It can update the charges variable of thePatientAccountclass.The student who designs the main program will design a menu that allows the user to enter a type of surgery and a type of medication, and check the patient out of the hospital. When the patient checks out, the total charges should be displayed.