As part of my C++ training, I wanted to create a basic complex number class for basic complex number calculations.
The class should have the following:
- constructor (non explicit, for implicit conversions)
<<
and>>
operators to stream withcout
andcin
==
,!=
operators to compare complex numbers+
,+=
,-
,-=
,*
,*=
,/
,/=
operators for simple arithmeticsGetR()
,GetI()
,SetR()
,SetI()
functions to access the real and imaginary parts of the number
I am going to work in a place that uses an underscore at the end of every function parameter, so I am sorry in advance for any discomfort it may cause while reviewing my code.
This is really a part of my baby steps in C++, so any feedback about style, design and coding will be appreciated. Attached are both the header file and the cpp file:
// complex.h
// Written by me on Jan 28, 2015
namespace exercises
{
class Complex;
std::ostream& operator<<(std::ostream&, const Complex&);
std::istream& operator>>(std::istream&, Complex&); // assumes (a,bi) format
bool operator==(const Complex, const Complex);
bool operator!=(const Complex, const Complex);
Complex operator+(const Complex, const Complex);
Complex operator-(const Complex, const Complex);
Complex operator*(const Complex, const Complex);
Complex operator/(const Complex, const Complex);
class Complex
{
public:
Complex(const double r_=0, const double i_=0);// non explicit on purpse
// using generated ~tor, cctor, c=tor
Complex& operator+=(const Complex);
Complex& operator-=(const Complex);
Complex& operator*=(const Complex);
Complex& operator/=(const Complex);
double GetR()const;
double GetI()const;
void SetR(const double);
void SetI(const double);
private:
double m_r;
double m_i;
};
} // namespace exercises
// complex.h
// Written by me on Jan 28, 2015
#include <iostream>
#include <cassert>
#include "complex.h"
namespace exercises
{
// ---------- global funcs ----------
bool operator==(const Complex a_, const Complex b_)
{
return (a_.GetR() == b_.GetR() && a_.GetI() == b_.GetI());
}
bool operator!=(const Complex a_, const Complex b_)
{
return (a_.GetR() != b_.GetR() && a_.GetI() != b_.GetI());
}
Complex operator+(const Complex a_, const Complex b_)
{
Complex ret(a_.GetR()+b_.GetR(), a_.GetI()+b_.GetI());
return ret;
}
Complex operator-(const Complex a_, const Complex b_)
{
Complex ret(a_.GetR()-b_.GetR(), a_.GetI()-b_.GetI());
return ret;
}
Complex operator*(const Complex a_, const Complex b_)
{
double a=a_.GetR(), b=a_.GetI();
double c=b_.GetR(), d=b_.GetI();
Complex ret(a*c-b*d, b*c+a*d);
return ret;
}
Complex operator/(const Complex a_, const Complex b_)
{
double a=a_.GetR(), b=a_.GetI();
double c=b_.GetR(), d=b_.GetI();
assert(c || d);
Complex ret((a*c+b*d)/(c*c+d*d), (b*c-a*d)/(c*c+d*d));
return ret;
}
std::ostream& operator<<(std::ostream& os_, const Complex& comp_)
{
return os_ << '(' << comp_.GetR() << ',' << comp_.GetI() << "i)";
}
std::istream& operator>>(std::istream& is_, Complex& comp_) // assumes (a,bi) format
{
char ch = 0;
double r = 0;
double i = 0;
is_ >> ch >> r >> ch >> i >> ch >> ch;
comp_.SetR(r);
comp_.SetI(i);
return is_;
}
// ---------- interface funcs ----------
Complex::Complex(const double r_, const double i_): m_r(r_), m_i(i_)
{}
Complex& Complex::operator+=(const Complex o_)
{
m_r += o_.m_r;
m_i += o_.m_i;
return *this;
}
Complex& Complex::operator-=(const Complex o_)
{
m_r -= o_.m_r;
m_i -= o_.m_i;
return *this;
}
Complex& Complex::operator*=(const Complex o_)
{
double a=m_r, b=m_i, c=o_.m_r, d=o_.m_i;
m_r = a*c - b*d;
m_i = b*c + a*d;
return *this;
}
Complex& Complex::operator/=(const Complex o_)
{
assert(o_.m_r || o_.m_i);
double a=m_r, b=o_.m_r, c=m_i, d=o_.m_i;
m_r = (a*c+b*d)/(c*c+d*d);
m_i = (b*c-a*d)/(c*c+d*d);
return *this;
}
double Complex::GetR()const
{
return m_r;
}
double Complex::GetI()const
{
return m_i;
}
void Complex::SetR(const double r_)
{
m_r = r_;
}
void Complex::SetI(const double i_)
{
m_i = i_;
}
} //namespace exercises