This assignment will give you an opportunity to practice C++ operator overloading best-practices (and other C++ best practices) in a reasonably simple context. You will need to implement a simple `Rational`

class that represents rational numbers as *numerator* / *denominator*. The goal will be to implement most of the basic arithmetic operators, as well as the stream-output operator.

Your `Rational`

class should be implemented in the files `rational.h`

and `rational.cpp`

. The class should also satisfy the following requirements:

Represent positive and negative rational numbers as two

`int`

values, numerator and denominator. The denominator should never be negative or zero; the numerator may be any whole number.Support initialization of the forms

`Rational{}`

(initializes to 0/1),`Rational{n}`

(initializes to`n`

/1), and`Rational{n, d}`

(initializes to`n`

/`d`

). If`d`

is 0, throw a`std::invalid_argument`

exception with a suitable error message. If`d`

is negative, invert the sign of both`n`

and`d`

so that`d`

is positive (for example,`Rational(-3, -5)`

= 3/5).Don't forget that functions can specify default arguments; that is a very easy way to implement this set of initialization call-patterns. Additionally, the one-argument call-pattern will allow the compiler to implicitly convert integers into

`Rational`

numbers.Provide a member function

`num()`

that returns the numerator, and another member function`denom()`

that returns the denominator.Provide a member function

`reciprocal()`

that returns a`Rational`

object containing the reciprocal of the number (but leaves the number itself unchanged). (This function should also throw if the reciprocal has a 0 for the denominator, but that will happen automatically if your constructor is implemented correctly.)Provide a member function

`reduce()`

that reduces the rational number such that the greatest common divisor of the numerator and denominator is 1. Note that this function should mutate the`Rational`

object that it is invoked on.You may find it helpful to implement a

`gcd(a, b)`

helper function; if you do this, make sure to put it in the`private`

section of your class.Also, if the numerator is 0 and the denominator is not 1, your

`reduce()`

function should modify the number to 0/1.Support addition, subtraction, multiplication and division with both the simple arithmetic and compound assignment operators.

All of these operations should generate a result that is fully reduced; for example, 2/5 + 6/10 = 1/1.

Recall that compound-assignment operators

`+=`

,`-=`

,`*=`

and`/=`

are best to implement as member operator-overloads, and the simple arithmetic operators`+`

,`-`

,`*`

and`/`

are best to implement as non-member operator overloads.Additionally, think about how you might reuse your work. For example, you might implement

`-=`

in terms of`+=`

, and`/=`

in terms of`*=`

using the`reciprocal()`

operation.Support stream-output using the

`<<`

operator. If the denominator is 1, only output the numerator; if the denominator is not 1, output "*numerator*/*denominator*".Make sure to follow

`const`

-correctness guidelines and use`const`

and references everywhere that is appropriate.Comment your class thoroughly in the Doxygen style, including a class-level description, and a comment for every data-member and member-function. (Comments may be brief if the function's purpose is obvious, but you must still comment all of these things.)

You do not need to create a

`Doxyfile`

or run Doxygen this time, as long as you follow the Doxygen format properly.Make sure to comment illegal arguments, and exceptions that may be thrown and the circumstances that would cause them to be thrown.

A test suite for your class is provided here; make sure to fix any test failures you encounter.

Now that you know how to use `make`

to automate your build process, create a `Makefile`

for your project that builds and tests your `Rational`

code.

The

`all`

target should build the test binary, but not run it.The

`test`

target should run the test binary.The

`clean`

target should delete`.o`

files and binaries.**As always, make sure to back up your code before testing your**`clean`

target for the first time!Make sure all files are compiled with the

`-Wall`

and`-Werror`

arguments (these will go in your`CXXFLAGS`

variable) so that any malformed but otherwise legal code is identified by the compiler.

Once you have completed the above tasks, submit your work through csman. Make sure to submit these files:

`Makefile`

`rational.h`

`rational.cpp`

You do not need to submit the test code; we will test your program with a fresh copy of these files.

Please also complete and submit a feedback survey with your submission, telling us about your experience with this assignment. Doing so will help us to improve CS11 Intro C++ in the future.

Copyright © 2018 by California Institute of Technology. All rights reserved. Generated from cpp-lab5.md.