5 Feb 1996
Outline
- A complex number class
- A stack class
Notes: 1) We will be handing out a copy of last year's quiz tomorrow.
Note that we're further along this year because we didn't
spend as much time covering C.
2) The handout on C++ Basics, Part 2 gives a pretty good explanation
of classes.
A complex number class
First, we need to select a representation. There are two obvious choices:
1. Store the real and imaginary components, both doubles.
2. Store the magnitude and angle, both doubles.
Let's pick (1), but keep that private.
/* the class definition belongs in a header file, say Complex.h */
class Complex{
/* we'll see what this means in a moment */
friend Complex product(Complex num1, Complex num2);
public:
Complex(double r=0.0, double i=0.0); // constructor, allows initialization
double magnitude();
double angle();
double real_part();
double imaginary_part();
private:
double real; // real component of number
double imaginary; // imaginary component of number
};
/* member functions belong in file Complex.c, listed below */
#include <iostream.h>
#include <math.h>
#include "Complex.h"
/* the following function constructs a complex number */
Complex::Complex(double r, double i){
real = r;
imaginary = i;
};
/* Complex numbers can now be created as follows: */
Complex new_num(1.0,-3.1); // new_num has been initialized
Complex new_num2; // new_num2 initialized to (0.0,0.0)
/* the following functions return the real and imaginary parts */
double Complex::real_part(){
return real;
};
double Complex::imaginary_part(){
return imaginary;
};
/* Why don't these functions take arguments? They are used as follows: */
cout << "The real part is " << new_num.real_part() << endl;
/* (This should print 1.0.) */
/* the following functions need math.h */
double Complex::magnitude(){
return sqrt((real*real)+(imaginary*imaginary));
};
double Complex::angle(){
return atan2(real,imaginary);
};
/* These two functions are not member functions. */
Complex sum(Complex num1, Complex num2){
Complex result(num1.real_part()+num2.real_part(),
num1.imaginary_part()+num2.imaginary_part());
return result;
};
/* We could make these functions a little faster & simpler if we made */
/* them friends of the Complex class. (See class definition.) */
Complex product(Complex num1, Complex num2){
Complex result;
result.real = (num1.real*num2.real)-(num1.imaginary*num2.imaginary);
result.imaginary = (num1.real*num2.imaginary)+(num1.imaginary*num2.real);
return result;
};
/* Some examples. */
Complex a(5.0,-32.4);
cout << "Angle: " << a.angle() << " Magnitude: " << a.magnitude() << endl;
Complex b(1.0,1.2);
Complex c;
c = sum(product(a,b),a); /* i.e., c = (a*b)+a */
cout << "(" << c.real_part() << "," << c.imaginary_part() << ")" << endl;
A stack class
/*
* Stack abstract data type. Empty Stack is represented by top = NULL.
*/
struct S_element {
int data;
struct S_element * next;
};
class Stack{
public:
Stack(); // constructor
~Stack(); // destructor
int is_empty();
int pop();
void push(int data);
private:
S_element *top;
};
/*
* Constructor
*/
Stack::Stack(void) {
top = NULL;
}
/*
* is_empty returns TRUE if the stack is empty.
*/
int Stack::is_empty(Stack * s) {
return (s->top == NULL);
}
/*
* Stack::pop removes the top of the stack from the stack, and
* returns the value of element just popped.
*/
int Stack::pop() {
int data;
S_element *next;
if (top == NULL) {
cerr << "Attempt to pop from an empty Stack." << endl;
return 0;
}
data = top->data;
next = top->next;
delete top;
top = next;
return data;
}
/*
* Stack::push pushes the given data onto the given stack
*/
void Stack::push(int data) {
S_element * newtop;
newtop = new S_element;
newtop->data = data;
newtop->next = top;
top = newtop;
}
/*
* Destructor (frees the entire stack)
*/
void Stack::~Stack() {
S_element *elt, *eltx;
for (elt = top; elt != NULL; elt = eltx) {
eltx = elt->next;
/* below we can do anything we want with the current element elt */
/* we are not depending on any of its fields to continue the loop */
delete elt;
}
}