Description
Member Operator Overloads
Workshop 5 (10 marks – 3.75% of your final grade)
In this workshop, you enable expression building for objects of a class type.
LEARNING OUTCOMES
Upon successful completion of this workshop, you will have demonstrated the abilities to:
• overload an operator as a member function of a class type
• access the current object from within a member function
• identify the lifetime of an object, including that of a temporary object
• describe what you have learned in completing this workshop
SUBMISSION POLICY
All your work (all the files you create or modify) must contain your name, Seneca email and student number.
You are responsible to back up your work regularly.
LATE SUBMISSION PENALTIES:
• In-lab portion submitted late, with at-home portion: 0 for in-lab. Maximum of 7/10 for the entire workshop.
• If any of in-lab, at-home or reflection portions is missing, the mark for the workshop will be 0/10.
IN-LAB (30%):
In this workshop, you are to design a class that represents fractions. Fractions are common in many domains. For example:
• in baking, recipe ingredients are often listed in fractional measures (1/2 cup of flour for 1 batch of cookie dough),
• in many commercials, retailers express statistics expressed in fractional form: o 4/5 dentists approve this toothpaste o 9/10 women prefer this lipstick
REVIEW OF FRACTIONS
A fraction is a number that can be represented as the ratio of one integer (numerator) over another integer (denominator). For example, 4/5, 3/7 and 12/2 are fractions; the 4, 3, and 12 are numerators and the 5, 7 and 2 are denominators. By convention, the denominator is expressed as a positive integer. A fraction with a denominator of 0 is ill-defined.
The following examples show the results of adding and multiplying two fractions – (a/b) and (c/d):
Addition: Multiplication:
YOUR TASK
Design and code a Fraction class that holds the information for a single fraction and defines the set of admissible operations on a Fraction object. The client function will use your design to evaluate expressions on Fraction objects. In other words, your Fraction class will offer the same functionality as other C++ built-in arithmetic types.
Store your class definition in a header file named Fraction.h and your member function definitions in an implementation file named Fraction.cpp.
Your design includes the following member functions:
default constructor (a constructor with no parameters): this constructor sets the object to a safe empty state;
constructor with 2 parameters: receives the numerator and denominator of a fraction, validates the data received and stores the received data only if it is valid. Your class treats data as valid if the numerator is not negative-valued and the denominator is positive-valued. If the data is invalid, this constructor sets the object to a safe empty state.
int max() const – a private query that returns the greater of the numerator and denominator
int min() const – a private query that returns the lesser of the numerator and denominator
void reduce() – a private modifier that reduces the numerator and denominator by dividing each by their greatest common divisor
int gcd() const – a private query that returns the greatest common divisor of the numerator and denominator (this code has been supplied)
bool isEmpty() const – returns true if the object is in a safe empty state; false otherwise
void display() const – inserts the fraction into standard output in the following form if the object holds a valid fraction and its denominator is not unit-valued (1)
NUMERATOR/DENOMINATOR
If the object holds a valid fraction and its denominator is unit-valued
(1), your function insert the fraction in the following format
NUMERATOR
If the object is in a safe empty state, your function inserts the string
no fraction stored
Fraction operator+(const Fraction& rhs) const – a public member query that receives an unmodifiable reference to a Fraction object. The object rhs represents the right operand of an addition expression. The current object represents the left operand. If both operands are nonempty Fractions, your function returns a copy of the result of the adding them together and reducing the result to lowest denominator (call reduce()). If either operand is in a safe empty state, your function returns an empty Fraction object.
Using the sample implementation of the w5_in_lab.cpp main module listed below, test your code and make sure that it works. The expected output from your program is listed below this source code. The output of your program should match exactly the expected one. IN-LAB MAIN MODULE
// Workshop 5: Operator Overloading
// File: w5_in_lab.cpp
// Version: 2.0
// Author: Chris Szalwinski
// Description:
// This file tests in-lab section of your workshop
/////////////////////////////////////////////
#include <iostream>
#include “Fraction.h”
using namespace std; using namespace sict;
int main() {
cout << “——————————” << endl; cout << “Fraction Class Test:” << endl;
cout << “——————————” << endl;
sict::Fraction a; cout << “Fraction a; // “; cout << “a = “;
a.display(); cout << endl;
Fraction b(1, 3);
cout << “Fraction b(1, 3); // “; cout << “b = “;
b.display(); cout << endl;
Fraction c(-5, 15);
cout << “Fraction c(-5, 15); //”;
cout << ” c = “; c.display(); cout << endl;
Fraction d(2, 4);
cout << “Fraction d(2, 4); //”; cout << ” d = “; d.display(); cout << endl;
Fraction e(8, 4);
cout << “Fraction e(8, 4); //”; cout << ” e = “; e.display(); cout << endl;
cout << “a + b equals “; (a + b).display(); cout << endl;
cout << “b + d equals “; (b + d).display(); cout << endl;
return 0;
}
IN-LAB OUTPUT
——————————
Fraction Class Test:
——————————
Fraction a; // a = no fraction stored
Fraction b(1, 3); // b = 1/3
Fraction c(-5, 15); // c = no fraction stored
Fraction d(2, 4); // d = 1/2 Fraction e(8, 4); // e = 2 a + b equals no fraction stored
b + d equals 5/6
IN-LAB SUBMISSION
Test and demonstrate execution of your program on Visual Studio using the main function listed above.
Upload Fraction.h, Fraction.cpp and w5_in_lab.cpp to your matrix account. Compile and run your code and make sure everything works properly.
Then, run the following command from your account (use your professor’s Seneca userid to replace profname.proflastname):
~profname.proflastname/submit 244_w5_lab<ENTER>
and follow the instructions.
IMPORTANT: Please note that a successful submission does not guarantee full credit
AT-HOME (30%)
For the at-home part of this workshop, add four more operators to the Fraction class of your in-lab solution. Implement the following member functions in the .cpp file of your Fraction module:
overload operator* as a query – your function receives an unmodifiable reference to a Fraction object, which represents the right operand of the expression. The current object represents the left operand. If both operands are non-empty fractions, your function returns a copy of the result of the multiplication operation in reduced form. If either operand is in a safe empty state, your function returns an empty Fraction object.
overload operator== as a query – your function receives an unmodifiable reference to a Fraction object, which represents the right operand of the expression. The current object represents the left operand. If both operands are non-empty fractions of equal value, your function returns true; false otherwise. If either operand is in a safe empty state, your function returns false.
overload operator!= as a query – your function receives an unmodifiable reference to a Fraction object, which represents the right operand of the expression. The current object represents the left operand. If both operands are non-empty fractions of unequal value, your function returns true; otherwise false. If either operand is in a safe empty state, your function returns false.
overload operator+= as a modifier – your function receives an unmodifiable reference to a Fraction object, which represents the right operand of the expression. The current object represents the left operand. If
both operands are non-empty fractions, your function stores the result of the addition operation in reduced form in the current object and returns a reference to the current object. If either operand is in a safe empty state, your function stores a safe empty Fraction object in the current object and returns a reference to the current object.
Code your implementation in such a way as to minimize the duplication of source code. Reuse your functions wherever possible.
Using the sample implementation of the w5_at_home.cpp main module shown below, test your code and make sure that it works correctly. The expected output from your program is below the source code. The output of your program should match exactly the expected one.
AT-HOME MAIN MODULE
// Workshop 5: Operator Overloading
// File: w5_at_home.cpp
// Version: 2.0
// Author: Chris Szalwinski
// Description:
// This file tests in-lab section of your workshop
/////////////////////////////////////////////
#include <iostream> #include “Fraction.h” using namespace sict; using namespace std;
int main() {
cout << “——————————” << endl; cout << “Fraction Class Test:” << endl;
cout << “——————————” << endl;
sict::Fraction a; cout << “Fraction a; // “; cout << “a = “;
a.display(); cout << endl;
Fraction b(1, 3);
cout << “Fraction b(1, 3); // “; cout << “b = “;
b.display(); cout << endl;
Fraction c(-5, 15);
cout << “Fraction c(-5, 15); //”; cout << ” c = “;
c.display(); cout << endl;
Fraction d(2, 4);
cout << “Fraction d(2, 4); //”; cout << ” d = “; d.display(); cout << endl;
Fraction e(8, 4);
cout << “Fraction e(8, 4); //”; cout << ” e = “; e.display(); cout << endl;
cout << “a + b equals “; (a + b).display(); cout << endl;
cout << “b + d equals “; (b + d).display(); cout << endl;
cout << “(b += d) equals “;
(b += d).display(); cout << endl;
cout << “b equals “; b.display(); cout << endl;
cout << “(a == c) equals “;
cout << ((a == c) ? “true” : “false”); cout << endl;
cout << “(a != c) equals “;
cout << ((a != c) ? “true” : “false”); cout << endl;
return 0;
}
AT-HOME OUTPUT
——————————
Fraction Class Test:
——————————
Fraction a; // a = no fraction stored
Fraction b(1, 3); // b = 1/3
Fraction c(-5, 15); // c = no fraction stored
Fraction d(2, 4); // d = 1/2 Fraction e(8, 4); // e = 2 a + b equals no fraction stored
b + d equals 5/6 (b += d) equals 5/6 b equals 5/6
(a == c) equals false
(a != c) equals false
REFLECTION (40%)
Create a file named reflect.txt that contains the answers to the following questions:
1. The operator+ returns a Fraction object. Explain why this operator should not return a reference to a Fraction object.
2. List the temporary objects in the w5_at_home.cpp main module.
3. List the simplifications that you made to your class to minimize code duplication.
4. Explain what you have learned in this workshop.
QUIZ REFLECTION
Add a section to reflect.txt called Quiz X Reflection. Replace the X with the number of the last quiz that you received and list the numbers of all questions that you answered incorrectly.
Then for each incorrectly answered question write your mistake and the correct answer to that question. If you have missed the last quiz, then write all the questions and their answers.
AT-HOME SUBMISSION
Test and demonstrate execution of your program on Visual Studio using the w5_at_home.cpp main module listed above.
Upload reflect.txt, Fraction.h, Fraction.cpp and w5_at_home.cpp to your matrix account. Compile and run your code and make sure everything works properly.
To submit, run the following commandt from your account and follow the instructions (use your professor’s Seneca userid to replace profname.proflastname):
~profname.proflastname/submit 244_w5_home<ENTER>
IMPORTANT: Please note that a successful submission does not guarantee full credit




Reviews
There are no reviews yet.