14.4. Accessor functions

Accessor functions should use the value name directly; the function signature shows whether the operation reads or writes the value. The return type, naturally, is the type of the corresponding instance variable.

In this case, the accessor functions give us an opportunity to make sure that the value of the variable is valid before we return it. Here’s what real looks like:

double complex_number::real ()
{
  if (m_cartesian == false) calculate_cartesian ();
  return m_real;
}

If the cartesian flag is true then real contains valid data, and we can just return it. Otherwise, we have to call calculate_cartesian to convert from polar coordinates to Cartesian coordinates:

void complex_number::calculate_cartesian ()
{
  m_real = m_mag * std::cos (m_theta);
  m_imag = m_mag * std::sin (m_theta);
  m_cartesian = true;
}

Assuming that the polar coordinates are valid, we can calculate the Cartesian coordinates using the formulas from the previous section. Then we set the cartesian flag, indicating that real and imag now contain valid data.

As an exercise, write a corresponding function called calculate_polar and then write mag and theta. One unusual thing about these accessor functions is that they are not const, because invoking them might modify the instance variables.

Take a look at the active code below, which uses the real accessor function.

Example c192_fourteenfour
 1#include <iostream>
 2#include <cmath>
 3
 4class complex_number
 5{
 6  double m_real = 0.0, m_imag = 0.0;
 7  double m_mag = 0.0, m_theta = 0.0;
 8  bool m_cartesian, m_polar;
 9
10public:
11  complex_number () { m_cartesian = true;  m_polar = false; }
12  complex_number (double r, double i)
13  {
14    m_real = r;  m_imag = i;
15    m_cartesian = true;  m_polar = false;
16  }
17  void calculate_cartesian ()
18  {
19    m_real = m_mag * std::cos (m_theta);
20    m_imag = m_mag * std::sin (m_theta);
21    m_cartesian = true;
22  }
23  double real ()
24  {
25    if (m_cartesian == false) calculate_cartesian ();
26    return m_real;
27  }
28  double imag ()
29  {
30    if (m_cartesian == false) calculate_cartesian ();
31    return m_imag;
32  }
33};
34
35int main() {
36  complex_number c1 (5.0, 3.5);
37  std::cout << c1.real() << ", " << c1.imag() << '\n';
38}

Write your implementation of calculate_polar in the commented area of the active code below. Once you're done with that, write the mag and theta accessor functions. Read the comments in main to see how we'll test if your functions works. If you get stuck, you can reveal the extra problem at the end for help.

Example c192_fourteenfive
 1#include <iostream>
 2#include <cmath>
 3
 4class complex_number
 5{
 6  double m_real = 0.0, m_imag = 0.0;
 7  double m_mag = 0.0, m_theta = 0.0;
 8  bool m_cartesian, m_polar;
 9
10public:
11  complex_number ();
12  complex_number (double r, double i);
13  void calculate_cartesian ();
14  double real ();
15  double imag ();
16  void calculate_polar ();
17  double mag ();
18  double theta ();
19};
20
21void complex_number::calculate_polar () {
22  // ``calculate_polar`` should convert the real and imaginary parts
23  // into magnitude and theta. Use the formula in the previous section.
24  // Write your implementation here.
25}
26
27double complex_number::mag () {
28  // ``mag`` should return the magnitude.
29  // Delete the return 0 and write your implementation here.
30  return 0;
31}
32
33double complex_number::theta () {
34  // ``mag`` should return the theta.
35  // Delete the return 0 and write your implementation here.
36  return 0;
37}
38
39int main() {
40  complex_number c1 (0.0, 1.0);
41  // Magnitude should be 1, theta should be pi/2, or about 1.5708
42  std::cout << c1.mag() << ", " << c1.theta() << '\n';
43}
Reveal Problem

Let's write the code for the calculate_polar function. Follow the format of the function calculate_cartesian.

  1.    m_cartesian = true;
    }
  2.    m_polar = true;
    }
  3. m_mag = std::pow(m_real, 2) + std::pow(m_imag, 2);
  4. m_mag = std::sqrt(std::pow(m_real, 2) + std::pow(m_imag, 2));
  5. m_theta = std::atan2(m_imag, m_real);
  6. void complex_number::calculate_cartesian () {
  7. void complex_number::calculate_polar () {

Reveal Problem

Let's write the code for the mag function, which should return the magnitude of a complex_number object.

  1.    calculate_polar ();
    }
  2.    return m_mag;
    }
  3. double complex_number::mag () {
  4. if (m_polar == false) {
  5. void complex_number::mag () {

Reveal Problem

Let's write the code for the theta function, which should return the magnitude of a complex_number object.

  1.    calculate_cartesian ();
    }
  2.    calculate_polar ();
    }
  3.    return m_theta;
    }
  4. double complex_number::mag () {
  5. double complex_number::theta () {
  6. if (m_polar == false) {