---
# System prepended metadata

title: Topic 7 Classes
tags: [Programming Design]

---

---
tags: Programming Design
title: Topic 7 Classes
---
# <font color="#1D617A">Topic 7</font> Classes
> Author: Benson Chiu (NTU IM)
> Inspector: Ruby (NTU IM)

## <font color="#1D617A">7.1</font> A simple analogy - Driving a car

- For people: Make the car go faster by pressing down on its accelerator pedal
    - Actually: **The pedal hides the complex machanisms** making the car faster
    - The pedal creates a **user-friendly interface** to the car's complex internal machanisms

     ![](https://i.imgur.com/37wYQB1.png =x200)


- Performing a task in a program requires a **function**
    - **Functions:** describe the mechanisms that actually perform 
    - Users can use the function directly without further knowledge into its machanism
    - The function is thus called ==**"Member Function"**==
    
- Analogy
    - An engineering drawing of a car -> ==**Class**==
    - Every Car -> Every ==**Object**==
    - Many **cars** can be built from the same **engineering drawing** -> Many ==**objects**== can be built from the ==**same class**==
    - Capabilities a car provides -> ==**Attributes**==
        - E.g. Its color, the number of doors......
        - **Every cars maintain its own attributes**


---

## <font color="#1D617A">7.2</font> Time Class
### Time class definition
```cpp=
#include<iostream>
#include<iomanip>
using namespace std;

class Time
{
public:
    Time(); //constructor
    void setTime( int, int, int ); //set hour, minute and second
    void printUniversal(); // print time in universal-time format
    void printStandard(); // print time in standard-time format

private:
    int hour; // 0 ~ 23 (24-hrs format)
    int minute; //0 ~ 59
    int second; //0 ~ 59
};

//Time constructor initializes each data member to zero.
//Ensure all Time objects start in a consisitent state.

Time::Time()
{
    hour  = minute = second = 0;
}

// set new Time value using the universal time; ensure that
// the data remains consistent by setting invalid values to zero
void Time::setTime( int h, int m, int s)
{
    hour = ( h >= 0 && h < 24 ) ? h : 0; // validate hour
    minute = ( m >= 0 && m < 60 ) ? m : 0; //validate minute
    second = ( s >= 0 && s < 60 ) ? s : 0; //validate second
}

// print Time in universal format (HH:MM:SS)
void Time::printUniversal()
{
    cout << setfill('0') << setw(2) << hour << ":"
    << setw(2) << minute << ":" << setw(2) <<second;
}

//print Time in standard-time format (HH:MM:SS AM or PM)
void Time::printStandard()
{
    cout << (( hour == 0 || hour == 12) ? 12 : hour % 12 ) << ":"
    << setfill('0') << setw(2) << minute << ":" << setw(2)
    << second << ( hour < 12 ? " AM":" PM");
    
}

int main()
{
    Time t; // instantiate object t of class time
    
    // output Time object t's initial values
    cout << "The initial universal time is ";
    t.printUniversal(); //00:00:00
    cout <<"\nThe initial standard time is ";
    t.printStandard(); //12:00:00 AM
    
    t.setTime(13, 27, 6); //change time
    
    //output Time object's new values
    cout << "\n\nUniversal after setTime is ";
    t.printUniversal(); //13:27:06
    cout << "\nStandard time after setTime is ";
    t.printStandard(); // 1:27:06 AM
    
    t.setTime(99, 99, 99); //attempt invalid settings
    //output t's values after specifying invalid values
    
    cout << "\n\nAfter attempting invalid settings:"
    <<"\nUniversal time: ";
    t.printUniversal();//00:00:00
    cout << "\nStandard time: ";
    t.printStandard(); //12:00:00 AM
    cout << endl;
}

```
### Expected output
![](https://i.imgur.com/8WME80h.png =x150)

---

### Code explanation
#### 1. Defining the class
```cpp=
class Time
{
public:
    Time(); //constructor
    void setTime( int, int, int ); //set hour, minute and second
    void printUniversal(); // print time in universal-time format
    void printStandard(); // print time in standard-time format

private:
    int hour; // 0 ~ 23 (24-hrs format)
    int minute; //0 ~ 59
    int second; //0 ~ 59
};
```
- By convention, the name of the class begin with a **capital letter**, and **every subsequent word** starts with capital letter
    - E.g. `TimeZone, CreateAndDestroy`
- Before the main function, we have to tell the compiler what **member functions** and **data members** belong to the class

:::info
Remember! The class definition terminates with a **semicolon (;)**
:::
----
#### 2. Declaring the `public` and `private` services

- Access specifiers: `public:` and `private:`
    - `public:` to indicate they can be called by other function in the program (such as `int main()`)
    - `private:`are accessible only to member functions for the class for which which they're declared
    - **Data hiding**: declaring data members with access specifier `private`

:::warning
Generally, data members should be declared `private` and member functions should be declared `public`
:::

---

#### 3. Class `Time`'s Constructor
```cpp=
//Time constructor initializes each data member to zero.
//Ensure all Time objects start in a consisitent state.

Time::Time()
{
    hour = minute = second = 0;
}
```


---

#### 4. `setTime` Member function

```cpp=
// set new Time value using the universal time, ensure that
// the data remains consistent by setting invalid values to zero

void Time::setTime( int h, int m, int s)
{
    hour = ( h >= 0 && h < 24 ) ? h : 0; // validate hour
    minute = ( m >= 0 && m < 60 ) ? m : 0; //validate minute
    second = ( s >= 0 && s < 60 ) ? s : 0; //validate second
}
```

----
#### 5. `printUniversal` Member function
```cpp=
// print Time in universal format (HH:MM:SS)
void Time::printUniversal()
{
    cout << setfill('0') << setw(2) << hour << ":"
    << setw(2) << minute << ":" << setw(2) <<second;
}
```
----
#### 6. `printStandard` Member function

```cpp=
//print Time in standard-time format (HH:MM:SS AM or PM)
void Time::printStandard()
{
    cout << (( hour == 0 || hour == 12) ? 12 : hour % 12 ) << ":"
    << setfill('0') << setw(2) << minute << ":" << setw(2)
    << second << ( hour < 12 ? " AM":" PM");
    
}
```
---
#### 7. Defining Member Functions Outside the Class Definiton: Class Scope
- When define a member function of a certain class **outside the definition of the class**, using `className :: funcName(...)`
- "::" is called the **binary scope resolution operator** 

---
#### 8. Using Class `Time`
```cpp=
Time sunset; //object of type time
Time arrayOfTimes[5]; //array of 5 time objects
Time &dinnerTime = sunset; //reference to a Time object
Time *timePtr = &dinnerTime //pointer to a Time object
```
- Using the member function of the object
    - Case-1: Using the dot operator (.)
        - E.g. `t.printUniversal()`
    - Case-2: When it's a pointer to a object
        - E.g. `tPtr -> printUniversal`
        - Which equals to `(*tPtr).printUniversal()`
---

## <font color="#1D617A">7.3</font> Class Scope and Accessing Class Members

###  <font color="#659DB4">Topic 1</font>  Class Scope

- Class's data members and member functions -> **Belongs to that class's scope**
- Nonmember functions -> Belongs to **global namespace scope**
- Class's member functions can be only overloaded by other member fuctions in the class
- The class-scope variable will be hidden by the local variable in the local scope
    - To use the global variable in the local block, use the scope resolution operator (::)
---
###  <font color="#659DB4">Topic 2</font>  Accessing Class's members

```cpp=
#include <iostream>
using namespace std;

class Count
{
public:
    //set the value of private data member x
    void setX(int value)
    {
        x = value;
    }
    
    //print the value of private data member x
    void print()
    {
        cout << x << endl;
    }
    
private:
    int x;
    
};

int main()
{
    Count counter; //create counter object
    Count *counterPtr = &counter; //create pointer to counter
    Count &counterRef = counter; //create reference to counter
    
    cout << "Set x to 1 and print using the object's name: ";
    counter.setX( 1 );
    counter.print();
    
    cout << "Set x to 2 and print using a reference to an object: ";
    counterRef.setX( 2 );
    counterRef.print();
    
    cout << "Set x to 3 and print using a pointer to an object: ";
    counterPtr -> setX( 3 );
    counterPtr -> print();
}

```
#### Catagarizing by the object types
- Objects and reference to an object
    - `objName.member`
- Pointer to an object
    - `objPtr -> member`

---

## <font color="#1D617A">7.4</font> Time Class: Separating Interface from Implementation

### Interface of a Class

- Define and Standardize the ways in which things such as people and systems interact one another
- The interface of a class describes $what$ service **a class's clients can use** and $how$ to **request services**, **==NOT==** $how$ the class carries out the service

### Seperating the Interface from Implementation
![](https://i.imgur.com/7SWzF86.png)

#### 1. `Time.h` Defining a Class's Interface in a Header File

```cpp=
#ifndef Time_h
#define Time_h

class Time
{
public:
    Time(); //constructor
    void setTime( int, int, int ); //set hour, minute and second
    void printUniversal(); // print time in universal-time format
    void printStandard(); // print time in standard-time format

private:
    int hour; // 0 ~ 23 (24-hrs format)
    int minute; //0 ~ 59
    int second; //0 ~ 59
};


#endif /* Time_h */
```

#### 2. Preprocessor Wrappers
```cpp=
//prevent multiple inclusions of header file
#ifndef Time_h //ifndef = If not defined
#define Time_h 
.......
#endif /* Time_h */
```

#### 3. `Time.cpp` Defining member function to a Sperate Source-Code file
```cpp=
#include <iostream>
#include <iomanip>
#include "Time.h" //include definiton of class Time from Time.h
using namespace std;

//Time constructor initializes each data member to zero.
//Ensure all Time objects start in a consisitent state.

Time::Time()
{
    hour  = minute = second = 0;
}

// set new Time value using the universal time; ensure that
// the data remains consistent by setting invalid values to zero
void Time::setTime( int h, int m, int s)
{
    hour = ( h >= 0 && h < 24 ) ? h : 0; // validate hour
    minute = ( m >= 0 && m < 60 ) ? m : 0; //validate minute
    second = ( s >= 0 && s < 60 ) ? s : 0; //validate second
}

// print Time in universal format (HH:MM:SS)
void Time::printUniversal()
{
    cout << setfill('0') << setw(2) << hour << ":"
    << setw(2) << minute << ":" << setw(2) <<second;
}

//print Time in standard-time format (HH:MM:SS AM or PM)
void Time::printStandard()
{
    cout << (( hour == 0 || hour == 12) ? 12 : hour % 12 ) << ":"
    << setfill('0') << setw(2) << minute << ":" << setw(2)
    << second << ( hour < 12 ? " AM":" PM");
    
}

```
#### 4. Testing `Class Time`
- **Driver program:** Seperate source-code file containing `int main()` to test our classes
- It's essential for large software developers to put main function in an independent file, in case that the clients will see the back mechanism of the classes

```cpp=
#include <iostream>
#include <iomanip>
#include "Time.h" //include definiton of class Time from Time.h
using namespace std;

int main()
{
    Time t; // instantiate object t of class time
    
    // output Time object t's initial values
    cout << "The initial universal time is ";
    t.printUniversal(); //00:00:00
    cout <<"\nThe initial standard time is ";
    t.printStandard(); //12:00:00 AM
    
    t.setTime(13, 27, 6); //change time
    
    //output Time object's new values
    cout << "\n\nUniversal after setTime is ";
    t.printUniversal(); //13:27:06
    cout << "\nStandard time after setTime is ";
    t.printStandard(); // 1:27:06 AM
    
    t.setTime(99, 99, 99); //attempt invalid settings
    //output t's values after specifying invalid values
    
    cout << "\n\nAfter attempting invalid settings:"
    <<"\nUniversal time: ";
    t.printUniversal();//00:00:00
    cout << "\nStandard time: ";
    t.printStandard(); //12:00:00 AM
    cout << endl;
}
```
#### 5. The Compilation and Linking Process
![](https://i.imgur.com/DnmEQiv.png)

- Two programmers
    - Class Implementation Programmers (GIP)
        - Create `Time.h` and `Time.cpp`
        - **Give `Time.h` to GCP**
    - Client Code Programmers (GCP)
        - Have to know the Time's **interface** to use the class
        - He/She is not given `Time.cpp`

#### Remark: Quotes(`""`) v.s. Brackets(`<>`)
- Quotes: Locate the header file **in the same directory** 
    - E.g. `#include "Time.h"` in the case above
- Brackets: Locate the header file in the **C++ Standard Library**
    - E.g. `#include<iostream>`


---
## <font color="#1D617A">7.5</font> Access Functions and Utility Functions

1. Access functions
    - Read and display data
    - Test the truth and the falsity of conditions / **predicate functions**

2. Utility functions
    - Also knowned as **helper functions**
    - It's a **private** member function ++that support the operation of the class's public member function++

---

![](https://i.imgur.com/7rl1QAR.png =x75)

### Code
*The code demonstrates the notion of **a utility function***

```cpp=
//SalesPerson.h

#ifndef SALESP_H
#define SALESP_H

class SalesPerson
{
public:
    static const int monthsPerYear = 12; // months in one year
    SalesPerson(); // constructor
    void getSalesFromUser(); // Input sales from keyboard
    void setSales( int, double ); //Set sales for a specific month
    void printAnnualSales(); // summarize and print sales
private:
    double totalAnnualSales(); // prototype for utility function
    double sales[ monthsPerYear ]; //12 monthly sales figures
};

#endif
```

```cpp=
//SalesPerson.cpp

#include <iostream>
#include <cstdlib>
#include <iomanip>
#include "SalesPerson.h" //include SalesPerson class definition
using namespace std;

//initialize elements of array sales to 0.0
SalesPerson::SalesPerson()
{
    for( int i = 0; i < monthsPerYear; i++)
        sales[i] = 0.0;
}

void SalesPerson::getSalesFromUser()
{
    double salesFigure;
    
    for ( int i = 1; i <= monthsPerYear; i++ )
    {
        cout<<"Enter sales amount for month "<<i<< ": ";
        cin >> salesFigure;
        setSales(i, salesFigure);
    }
}

// Set one of the 12 monthly sales figures; function subtracts
// one from month value for proper subscript in sales array
void SalesPerson::setSales(int month, double amount)
{
    //test for valid month and amount values
    if (month >= 1 && month <= monthsPerYear && amount > 0 )
        sales[ month - 1 ] = amount; //adjust for subscript 0-11
    else //invalid month and amount value
        cout << "Invalid month or sales figure" << endl;
}

//print total annual sales
void SalesPerson::printAnnualSales()
{
    cout << setprecision(2) << fixed << "\n The total annual sales are: $"
    << totalAnnualSales() << endl; //call utility function
}

double SalesPerson::totalAnnualSales()
{
    double total = 0.0;
    
    for( int i = 0; i < monthsPerYear; i++)
        total += sales[i];
    
    return total;
}
```

```cpp=
//main.cpp

#include "SalesPerson.h"

int main()
{
    SalesPerson s; //create SalesPerson object s
    s.getSalesFromUser(); //note simple sequential code; there are
    s.printAnnualSales();//no control statements in main
}

```
### Expected Output
![](https://i.imgur.com/Mjg8h0d.png =x200)

