This lab will help you practice with classes.
Design and code a class for a complex number ADT. To refresh your memory, complex numbers have the form: a+bi. Where a is the real part, b is the imaginary part, and i represents the square root of -1 (which doesn't exist and is therefore imaginary).
Standard mathematical operations are defined on complex numbers:
a+bi + c+di = (a+c) + (b+d)i a+bi - c+di = (a-c) + (b-d)i a+bi * c+di = (a*c-b*d) + (a*d+b*c)i // i*i == -1 (a*c+b*d) - (a*d-b*c)i a+bi / c+di = ---------------------- c*c + d*d
And special operations are also defined:
___________ |a+bi| = \/ a*a + b*b // magnitude ____ a+bi = a-bi // conjugate
Define these operations (along with construction, input/output, and access/mutation) for your ADT class. Place your ADT in a library. (You may find the notes elsewhere on the site somewhat helpful.)
Write a driver to test the ADT's operations.
Why do your class methods take fewer arguments than you might/would expect?
Does your addition method change the value of the calling object? Should it? Does the compiler change x when you have x+y in your program? What about y? Does/Should your addition method change the other complex number? Does this extend to the other operations? How do you tell the compiler about your decisions?
What kind of value should be returned from the standard math operations (i.e. what TYPE of value)? From conjugate? From magnitude?
Does your input method prompt the user? Why shouldn't it?
Does your output method print anything besides the complex number (using proper notation) — even an endl? Why shouldn't it?
This assignment is (Level 5).
Add (Level 2) to properly apply inline'ing and const-ness to all of your class methods. (This includes proper use of initialization lists on constructors!)
Should any of your methods be inline'd for speed? Which ones will you inline? How does one do this for a class method?
If you end up inline'ing all of your methods, do you still need an implementation file for your library? Why/Why not?
Do the accessors, output, or math operation methods alter the calling object in any way? How do you specify such a situation to the compiler so it can better handle/enforce your decision?
What needs to be in your constructor initialization lists? Is there a certain order to the list? Does it go on the prototype or the definition?
The curious amongst you probably noticed these relationships when exploring complex numbers:
2 ____ |a+bi| = a+bi * a+bi ____ a+bi a+bi * c+di ------ = ------------- c+di 2 |c+di|
So you can define some standard operations in terms of a mixture of conjugate and magnitude. If you do so, I'll add an additional (Level 1.5) to this lab.
Noticing the repetitive nature of the square of the magnitude in these two formulas, should you make this a helper function? Would this function prove useful outside the class? If not, how should you indicate this to the compiler? If so, what would they use it for?
Add (Level 2) for overloading your math operations to allow addition, etc. of complex numbers with built-in floating point types. (What should be the result?)
Add (Level 1) for making a nice menu-based driver rather than a plain old yes-no driver.