Skip to main content
2 of 3
added 2 characters in body; edited tags
RubberDuck
  • 30.9k
  • 6
  • 71
  • 174

Simple complex number class

This is my first time writing C++, so I would appreciate advice in the areas of:

  • Code style (naming conventions, indentation, etc)
  • Memory usage (am I performing unnecessary object copies?)
  • Class design (move constructors, destructors, etc, are they necessary?)
  • Correct usage of standard library functions (especially the string parsing part)

#complex.h:

#ifndef COMPLEX_H
#define COMPLEX_H

#include <string>

class Complex
{
private:
    double real_;
    double imag_;

public:
    Complex();
    Complex(const Complex& obj);
    Complex(const std::string& str);
    Complex(double real);
    Complex(double real, double imag);
    double real() const;
    double imaginary() const;
    double argument() const;
    double modulus() const;
    Complex conjugate() const;
    Complex pow(double power) const;
    std::string toString() const;
    Complex operator+(const Complex& rhs) const;
    Complex operator-(const Complex& rhs) const;
    Complex operator*(const Complex& rhs) const;
    Complex operator/(const Complex& rhs) const;
    bool operator==(const Complex& rhs) const;
    bool operator!=(const Complex& rhs) const;
};

#endif

#complex.cpp:

#include <cmath>
#include <sstream>
#include <regex>

#include "complex.h"

Complex::Complex(const Complex& obj) : Complex(obj.real_, obj.imag_) { }

Complex::Complex(const std::string& str) {
    double real = 0.0, imag = 0.0;
    std::regex realRegex("^(-)?\\s*(\\d+(\\.\\d+)?)$");
    std::regex imagRegex("^(-)?\\s*(\\d+(\\.\\d+)?)i$");
    std::regex bothRegex("^(-)?\\s*(\\d+(\\.\\d+)?)\\s*([-+])\\s*(\\d+(\\.\\d+)?)i$");
    std::smatch match;
    if (std::regex_match(str.begin(), str.end(), match, realRegex)) {
        real = std::atof(match[2].str().c_str());
        if (match[1].matched) {
            real = -real;
        }
    } else if (std::regex_match(str.begin(), str.end(), match, imagRegex)) {
        imag = std::atof(match[2].str().c_str());
        if (match[1].matched) {
            imag = -imag;
        }
    } else if (std::regex_match(str.begin(), str.end(), match, bothRegex)) {
        real = std::atof(match[2].str().c_str());
        imag = std::atof(match[5].str().c_str());
        if (match[1].matched) {
            real = -real;
        }
        if (match[4].str() == "-") {
            imag = -imag;
        }
    } else {
        throw std::runtime_error("Invalid number format");
    }
    real_ = real;
    imag_ = imag;
}

Complex::Complex() : Complex(0.0) { }

Complex::Complex(double real) : Complex(real, 0.0) { }

Complex::Complex(double real, double imag) : real_(real), imag_(imag) { }

double Complex::real() const {
    return real_;
}

double Complex::imaginary() const {
    return imag_;
}

double Complex::argument() const {
    return std::atan2(imag_, real_);
}

double Complex::modulus() const {
    return std::sqrt(real_ * real_ + imag_ * imag_);
}

Complex Complex::conjugate() const {
    Complex result(real_, -imag_);
    return result;
}

Complex Complex::pow(double power) const {
    double mod = modulus();
    double arg = argument();
    mod = std::pow(mod, power);
    arg *= power;
    double real = mod * std::cos(arg);
    double imag = mod * std::sin(arg);
    Complex result(real, imag);
    return result;
}

std::string Complex::toString() const {
    std::stringstream fmt;
    if (imag_ == 0) {
        fmt << real_;
    } else if (real_ == 0) {
        fmt << imag_ << "i";
    } else {
        fmt << real_;
        if (imag_ < 0) {
            fmt << " - " << -imag_;
        } else {
            fmt << " + " << imag_;
        }
        fmt << "i";
    }
    return fmt.str();
}

Complex Complex::operator+(const Complex& rhs) const {
    Complex result(real_ + rhs.real_, imag_ + rhs.imag_);
    return result;
}

Complex Complex::operator-(const Complex& rhs) const {
    Complex result(real_ - rhs.real_, imag_ - rhs.imag_);
    return result;
}

Complex Complex::operator*(const Complex& rhs) const {
    double newReal = real_ * rhs.real_ - imag_ * rhs.imag_;
    double newImag = real_ * rhs.imag_ + imag_ * rhs.real_;
    Complex result(newReal, newImag);
    return result;
}

Complex Complex::operator/(const Complex& rhs) const {
    double denom = rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_;
    double newReal = (real_ * rhs.real_ + imag_ * rhs.imag_) / denom;
    double newImag = (imag_ * rhs.real_ - real_ * rhs.imag_) / denom;
    Complex result(newReal, newImag);
    return result;
}

bool Complex::operator==(const Complex& rhs) const {
    return real_ == rhs.real_ && imag_ == rhs.imag_;
}

bool Complex::operator!=(const Complex& rhs) const {
    return !(*this == rhs);
}
Andrew Sun
  • 304
  • 3
  • 9