Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

LAB (100%) The Numbers Module Your task for this lab is to complete the implementation of the ** Numbers ** class. This class, when created

LAB (100%) The Numbers Module

Your task for this lab is to complete the implementation of the **Numbers** class.

This class, when created using a filename as its constructor argument, reads several double values from the file (assuming there is one number per line in the file) and holds them dynamically in memory. Then the caller application has the option of adding numbers to the collection.

## streaming on ostream

If inserted into ostream this class, provides the following information about the numbers kept in the object:

- The Module can stream the values in ascending order (if sorted).

- The Module streams the largest, the smallest and the average of the values in the collection

Also, The **Numbers** class has the following capabilities:

- A **Numbers** object can safely be copied or assigned to another **Numbers** object; however, if copied, then the values kept in the copied object will not be written back into the file.

- A **Numbers** object can be displayed or streamed into an ostream object.

- A **Numbers** object can be extracted or read from an istream object.

When the **Numbers** object goes out of scope the double values kept in the object should overwrite the old values in the file, ONLY IF the object is the original object and not a copy.

# The Numbers class

The Numbers class has at least the following five attributes:

- a double pointer to hold the address of the dynamic array of doubles that keeps the number read from the file
*(we will call this array, the **Collection** from now on)*

- a 255-character long cString to hold the name of the file associated with the class
*(we will call this cString, the **file name** from now on)*

- an integer (preferably unsigned) to hold the number of double numbers in the **Collection**.
*(We will call this **Collection Size** from now on)*

- a Boolean flag to keep track if this object is the original or a copy.
*(We will call this the **original flag** from now on)*

- a Boolean flag to keep track if any number was added to the collection.
*(We will call this the **added flag** from now on)*

## Constructors, Destructor and Copy Operations (Construction and Assignment)

The **Numbers** class can be instantiated in three different ways:

### One argument constructor

Creates an original instance of the Numbers class by receiving the data file name (a Cstring) as an argument

- Sets the **file name** to the argument value

- calls the [load()](#load) function

### Default constructor

- Sets the object to [a safe empty state](#setempty).

### Destructor

- Saves the file by calling the [save()](#save) function

- deletes the **Collection** pointer

### Copy Constructor

Creates a copy out of an already existing **Numbers** object.

The standard way of doing this is as follows:

- Make sure the class is in a safe empty state

- call the copy assignment operator to reuse your logic for copying the object.

### Copy Assignment Operator

If this is not a self-copy, proceed with the copying procedure, otherwise, skip the whole process and end the operation

#### Copying procedure

- save the **Collection** calling the [save()](#save) function. This will save the original values that are about to be replaced.

- delete the current **Collection**

- set the current object to the empty state; this will make sure the object remains empty if the source (right operand) is empty.

- if the right operand is in a good state (not empty)

- sets the **original flag** to false (not original)

- Allocates new memory for the **Collection** to the size of the right operand's **Collection size**

- Copies all the double values of the right operand **Collection** to the newly allocated **Collection**.

- updates the **Collection size**

#### Ending the operation

- in any case, return the reference of the current object.

## Member Functions and Member operator+= overload

### Private methods:

#### void sort(double* array, unsigned int size) (implemented)

sorts an array of doubles in ascending order.

> This could be moved to the Utils module if you have one!

#### countLines() (implemented)

This function returns the number of lines in the **data file** (hence returning the number of double values in the file).

> Note that if the number returned by this method and the actual number of successful reads from the file don't match, the **data file** is corrupted and the object must be set back to an empty state (see the [load()](#load) function)

This method can not change the state of the current object.

#### setEmpty()

Sets all attributes to null, zero, false or empty Cstring.

#### load()

This function returns true if all the double values are read from the **data file** and stored in the **Collection**, otherwise returns false.

- Delete the current **Collection**

- Call the [countLines()](#countlines-implemented) and get the number of lines in the file.

- If the number of lines is greater than zero (the file is not empty)

- Allocate memory to the number of lines (that is what the number of double values in the file should be) and keep the address in the **Collection** pointer.

- Create an instance of ifstream for reading the data file using the **file name**

- While the ifstream object is in a good state, keep reading double values from the file into the elements of the **Collection** (as you do with cin) and count the number of reads

- If the number of lines and the number of successful reads do not match discard all the read and set the object back to an empty state as mentioned in [countLines()](#countlines-implemented) function. Otherwise set the **Collection size** to the number of double values read and set the **original flag** to true.

- At the end return true if at least one number was read successfully

#### save()

- If the current object is an original and new values are added to it, then

- Create an instance of ofstream to overwrite the data file (using the **file name**)

- Set the precision of the floating point numbers to 2 digits after the decimal point when writing the number into the file.

- Write all the elements of the **Collection** using the ofstream object (as you do with cout).

- Write a newline after each double value.

#### max()

Returns the largest double number in the **Collection**

> This method can not change the state of the current object

#### min()

Returns the smallest double number in the **Collection**

> This method can not change the state of the current object

#### average()

Returns the average of the double numbers in the **Collection**.

> This method can not change the state of the current object

### Pubic:

#### Boolean type conversion operator overload (bool cast overload)

Returns true if the **Numbers** object is in a good state (not empty) and false if it is not

(i.e. returns true if **Collection** pointer is not nullptr)

> This method can not change the state of the current object

#### sort()

calls the provided [sort](#void-sortdouble-collectionptr-unsigned-int-size-implemented) function to sort the **Collection** double array.

#### Operator +=

Overload the += operator to add a single double value to the list of numbers in the array and then return the reference of the current object, only if the **Numbers** object is not empty.

You need to increase the size of the allocated memory by one (add one double to the **Collection**), to be able to do this.

Here is the sequence of the actions to be taken to resize memory:

- if the current object is not empty

- Create a temporary local double-pointer and allocate memory with the increased size

- Copy all the current values from the **Collection** to the newly allocated memory.

- Update the size of the data to the new size

- Now that all the values are copied to the new memory, delete the original **Collection** pointer

- Set the original **Collection** pointer to point to newly allocated memory

- Update the **Collection size**

- return the reference of the current object.

View the Slides

#### display function. (to be implemented)

```C++

std::ostream& display(std::ostream& ostr = std::cout) const

```

Inserts the **file name**, the **Collection** numbers and the largest, smallest and average values into the `ostream` reference argument in the following format:

- if the object is empty, insert: `"Empty list"`.

- if the object is not empty

- set the precision to print two digits after the decimal point.

- if the **Numbers** object is not original insert `"Copy Of "`

- insert the **file name**

- New line

- insert all the number in the **Collection** comma separated like the following example:

`1.99, 99.99, 5.12`

- New line

- insert a line with 76 dashes (`-`).

- insert the **Collection** information exactly as the following example:

`Total of 99 number(s), Largest: 99.99, Smallest: 99.99, Average: 99.99`

- New line

- insert a line with 76 assignment signs (`=`).

- return the reference of the ostream.

### Helper Functions

- Overload the insertion operator so a **Numbers** object can be inserted into an ostream object.

- Overload the extraction operator so a **Numbers** object can be extracted an istream object.

(without using `freind` statement)

> hint: you can use the operator+= overload

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Understanding Oracle APEX 5 Application Development

Authors: Edward Sciore

2nd Edition

1484209893, 9781484209899

Students also viewed these Databases questions

Question

What is your proudest accomplishment?

Answered: 1 week ago

Question

Have to Do: Recognize improvement.

Answered: 1 week ago