Question: This assignment introduces the concept of operator overloading , the use of the friend keyword, and the concept of const correctness. A number of the

This assignment introduces the concept of operator overloading, the use of the friend keyword, and the concept of "const correctness".

A number of the form a + ib, where i2 = -1 and a and b are real numbers, is called a complex number. We call a the real part and b the imaginary part of a + ib. Complex numbers can also be represented as ordered pairs (a, b). The addition and multiplication of complex numbers is defined by the following rules:

(a + ib) + (c + id) = (a + c) + i(b + d)

(a + ib) * (c + id) = (ac - bd) + i(ad + bc)

Using the ordered pair notation, these rules are written as:

(a, b) + (c, d) = ((a + c), (b + d))

(a, b) * (c, d) = ((ac - bd), (ad + bc))

C++ has a standard library class that represents complex numbers defined in the header file . However, in this assignment we will create our own new data type, complex, to process complex numbers. We will overload the stream insertion and stream extraction operators for easy input and output. We will also overload the operators + and * to perform addition and multiplication of complex numbers. If x and y are complex numbers, we can evaluate expressions such as x + y and x * y.

More information on complex numbers can be found here, but the description given above should be sufficient to complete this assignment.

1. Initial Setup

  1. Log in to Unix.

  2. Run the setup script for Assignment 6 by typing:

     setup 6 

2. Files You Must Write

You will need to write one class for this assignment. A main program to test your class will be provided.

The complex class

The complex class represents a complex number as an ordered pair. Like the other classes we've written this semester, this class should be implemented as two separate files.

The class definition should be placed in a header file called complex.h. Include header guards to prevent it from accidentally being #included more than once in the same source code file.

The complex class should contain the following private data members:

  • a double to store the real part of the complex number.
  • another double to store the imaginary part of the complex number.

In addition to the data members described above, the class definition should also contain prototypes for the member functions described below.

The implementations of the class member functions should be placed in a separate source code file called complex.cpp. Make sure to #include "complex.h" at the top of this file.

The complex class should have the following member functions (most of which are quite small):

  • complex constructor

    Parameters: The constructor should take two double variables as arguments, representing the real and imaginary parts of a complex number. Give the two parameters the default value 0 in the prototype for the constructor (which will allow this constructor to double as a "default" constructor) See the page on Default Function Arguments.

    Logic: Assign the function parameters to the corresponding data members.

  • set_complex()

    Parameters: This member function takes two double variables as arguments, representing the real and imaginary parts of a complex number.

    Returns: Nothing.

    Logic: Assign the function parameters to the corresponding data members.

  • tuple complex::get_complex() const

    Parameters: None.

    Returns: This function returns a special C++ compound data type called a tuple. This will allow us to return more than one value from a function (two double variables in this case).

    Logic: Return the result of calling the standard library function make_tuple(), passing it the real part and the imaginary part of the complex number. This can all be done in a single return statement.

    This member function does not alter any data members of the object that called the member function, so it is declared to be const.

    To use the tuple data type, you must #include . Both tuple and make_tuple are part of the namespace std. You can read more about the tuple data type on this page.

  • set_real()

    Parameters: A double, representing the real part of a complex number.

    Returns: Nothing.

    Logic: Assign the function parameter to the real part data member of the object that called the member function.

  • get_real()

    Parameters: None.

    Returns: The real part of the complex number (a double).

    Logic: Return the data member representing the real part of the complex number.

    This member function does not alter any data members of the object that called the member function, so it should be declared const.

  • set_imaginary()

    Parameters: A double, representing the imaginary part of a complex number.

    Returns: Nothing.

    Logic: Assign the function parameter to the imaginary part data member of the object that called the member function.

  • get_imaginary()

    Parameters: None.

    Returns: The imaginary part of the complex number (a double).

    Logic: Return the data member representing the imaginary part of the complex number.

    This member function does not alter any data members of the object that called the member function, so it should be declared const.

  • operator+()

    This member function will be called when the operator + is used to add two complex objects. For example:

     // Assume c1, c2, and c3 are complex objects c3 = c1 + c2 // Generates this member function call: c1.operator+(c2); 

    Parameters: This member function takes one parameter, a reference to a constant complex object, representing the right operand of the arithmetic expression. The left operand of the expression is represented by this, which points to the complex object that called the member function.

    Returns: A complex object that holds the result of the arithmetic.

    Logic: Declare a complex object to hold the result of the arithmetic. You will need to set the real part and the imaginary part of this result object to the correct values, as outlined in the ordered pair version of the addition rule shown at the beginning of the assignment sheet. For example, the real part of the result object should be set to the sum of the real part of the left operand (which corresponds to the variable a in the rule) and the real part of the right operand (which corresponds to the variable c in the rule). Once you've done the arithmetic, return the result object.

    This member function does not alter any data members of the object that called the member function, so it should be declared const.

  • operator*()

    This member function will be called when the operator * is used to multiply two complex objects. For example:

     // Assume c1, c2, and c3 are complex objects c3 = c1 * c2 // Generates this member function call: c1.operator*(c2); 

    Parameters: This member function takes one parameter, a reference to a constant complex object, representing the right operand of the arithmetic expression. The left operand of the expression is represented by this, which points to the complex object that called the member function.

    Returns: A complex object that holds the result of the arithmetic.

    Logic: Declare a complex object to hold the result of the arithmetic. You will need to set the real part and the imaginary part of this result object to the correct values, as outlined in the ordered pair version of the multiplication rule shown at the beginning of the assignment sheet. Once you've done the arithmetic, return the result object.

    This member function does not alter any data members of the object that called the member function, so it should be declared const.

  • operator==()

    This member function will be called when the operator == is used to compare two complex objects. For example:

     // Assume c1 and c2 are complex objects if (c1 == c2) // Generates this member function call: c1.operator==(c2); 

    Parameters: This member function takes one parameter, a reference to a constant complex object, representing the right operand of the relational expression. The left operand of the expression is represented by this, which points to the complex object that called the member function.

    Returns: A boolean value.

    Logic: The member function should return true if the real part of the left operand equals the real part of the right operand AND the imaginary part of the left operand equals the imaginary part of the right operand. Otherwise, the member function should return false.

    This member function does not alter any data members of the object that called the member function, so it should be declared const.

In addition to the member functions described above, you will need to write two standalone functions. These functions are not (and can not be) member functions. You should

  1. Include a friend declaration for each of these functions in the complex class definition.
  2. Put the definitions for these functions in complex.cpp.
  • operator<<()

    This function will be called when the stream insertion operator << is used to print a complex object. For example:

     complex c(3, 5); // A complex number cout << c; // Generates this function call: operator<<(cout, c); 

    In the example code above, the ostream object cout (the left operand in the stream insertion expression) will be passed to the function as the first parameter, while the complex object c (the right operand) will be passed to the function as the second parameter.

    Parameters: This function takes two parameters. The first is a reference to an ostream object, representing the left operand of the stream insertion expression. The second is a reference to a constant complex object, representing the right operand of the expression.

    Returns: A reference to an ostream object (i.e., the first parameter).

    Logic: This function should print a complex object as an ordered pair of the form:

     (real part, imaginary part) 

    So printing the object c from the example above should produce the output:

     (3, 5) 

    You can use the left operand parameter to print a left parenthesis:

     os << '('; // "os" is the reference to an ostream object // passed into the member function as the 1st parameter 

    In similar fashion, you can use the left operand and the << operator to print the real part of the right operand, followed by a comma, a space, the imaginary part of the right operand, and a right parenthesis. At the end of the function, return the left operand (to allow cascading of the << operator to work correctly).

  • operator>>()

    This function will be called when the stream extraction operator >> is used to read a complex object. For example:

     complex c; // A complex number cin >> c; // Compiler generated function call: operator>>(cin, c); 

    In the example code above, the istream object cin (the left operand in the stream extraction expression) will be passed to the function as the first parameter, while the complex object c (the right operand) will be passed to the function as the second parameter.

    Parameters: This function takes two parameters. The first is a reference to an istream object, representing the left operand of the stream extraction expression. The second is a reference to a complex object, representing the right operand of the expression.

    Returns: A reference to an istream object (i.e., the first parameter).

    Logic: This function should read input entered by the user as an ordered pair of the form:

     (real part, imaginary part) 

    You can use the left operand parameter to read the left parenthesis entered by the user into a char variable:

     char ch; is >> ch; // "is" is the reference to an istream object // passed into the member function as the 1st parameter 

    (You don't need to do anything with parenthesis once it's been read. We just need to get it out of the way so we can read the stuff that's important.)

    Once the left parenthesis has been read, you can then read the real part of the input entered by the user into the real part of the right operand object. Then read the comma into your char variable. Read the imaginary part of the input entered by the user into the imaginary part of the right operand object. Then read the right parenthesis entered by the user into the char variable. Finally, return the left operand (to allow cascading of the >> operator to work correctly).

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!