Listing 4 Corrected listing 4 from "Mutable Class Members", CUJ, April 1995

// z2.cpp - a rudimentary class for complex numbers
// using "lazy" evaluation polar form
#include <iostream.h>
#include <iomanip.h>
#include <math.h>

class complex
   {
public:
   complex(double r, double i);
   complex(const complex &z);
   complex &operator=(const complex &z);
   ~complex();
   double real() const;
   double imag() const;
   double rho() const;
   double theta() const;
   static int count;
private:
   double re, im;
   struct polar;
   polar *p;
   };

struct complex::polar
   {
   polar(double r, double t);
   ~polar( ):
   double rho, theta;
   static int count;
   };

int complex::polar::count = 0;

inline complex::polar::polar(double r, double t)
   : rho(r), theta(t)
   {
   cout << "polar() [" << ++count << "]\n";
   }

inline complex::polar::~polar()
   {
   cout << "~polar() [" << count-- << "]\n";
   }

int complex::count = 0;

inline complex::complex(double r, double i)
   : re(r), im(i), p(0)
   {
   cout << "complex() [" << ++count << "]\n";
   }

inline complex::complex(const complex &z)
   : re(z.re), im(z.im), p(0)
   {
   }

//
// This was the culprit...
//

inline complex &complex::operator=(const complex &z)
   {
   f (this != &z]   // this is new
      {
      re = z. re;
      im = z. im;
      delete p;   // this is new
      p = 0;
      }
   return *this;
   }

inline complex::~complex()
   {
   delete p;
   cout << "~complex() [" << count-- << "]\n";
   }

inline double complex::real() const
   {
   return re;
   }

inline double complex::imag( ) const
   {
   return im;
   }

double complex::rho() const
   {
   if (p == 0)
      {
      complex *This = const_cast<complex *>(this);
      This->p =
         new polar(sqrt(re*re + im*im), atan2(im, re));
      }
   return p->rho;
   }

double complex::theta() const
   {
   if (p == 0)
      (polar *&)p =
         new polar(sqrt(re*re + im*im), atan2(im, re));
   return p-> theta;
   }

complex operator+(const complex &z1, const complex &z2)
   {
   return complex
      (z1.real() + z2.real(), z1.imag() + z2.imag());
   }

int main()
   {
   complex z1(3, 4);
   cout << '(' << z1.real() << ',' << z1.imag() << ')'
      << endl;
   cout << '(' << z1.rho() << ',' << z1.theta() << ')'
      << endl;
   complex z2(1, 1);
   cout << '(' << z2.real() << ',' << z2.imag() << ')'
      << endl;
   cout << '(' << z2.rho() << ',' << z2.theta() << ')'
      << endl;
   z1 = z1 + z2;
   cout << '(' << z1.real() << ',' << z1.imag() << )'
      << endl;
   cout << '(' << z1.rho() << ',' << z1.theta() <<4 ')'
      << endl;
   return 0;
   }

// End of File