自定義實現Complex類

三三三三三三外發表於2020-11-05
// complex.h
// 防衛式的巨集定義
#ifndef __COMPLEX__
#define __COMPLEX__

/* forward declarations */
using std::ostream;
class Complex;

Complex&
__doapl(Complex*, const Complex&);

/* class declarations */
class Complex
{
public:
    Complex(double r = 0, double i = 0) : re(r), im(i) {}
    double real() const {return re;}
    double imag() const {return im;}
    Complex& operator += (const Complex&);
private:
    double re, im;
    
    friend Complex& __doapl(Complex*, const Complex&);
};

/* class definition */
inline Complex&
__doapl(Complex* ths, const Complex& r) {
    ths->re += r.re;
    ths->im += r.im;
    return *ths;
}

// 成員函式作用在左值, a+=b => a.operator+=(b)
// 建議編譯器使用inline
// 為了可以連續使用+=, 因此返回值是Complex&, 不是void
inline Complex&
Complex::operator += (const Complex& r) {
    return __doapl(this, r);
}

// 如果寫成成員函式就需要寫成 complex<<cout
// 因此需要寫成全域性函式, 第一個是ostream物件(會被改變), 第二個引數是需要輸出的
ostream&
operator << (ostream& os, const Complex& c) {
    return os<<"("<<c.real()<<","<<c.imag()<<")";
}

// 如果把+運算子過載設計成成員函式, 那麼只能實現complex+一個數, 不能實現一個數+complex
// 因為成員函式是作用於左值的, 所以complex必須在左邊
inline Complex
operator + (const Complex& c1, const Complex& c2) {
    return Complex(c1.real() + c2.real(),
                   c1.imag() + c2.imag());
}

inline Complex
operator + (const Complex& c1, double d) {
    return Complex(c1.real() + d, c1.imag());
}

inline Complex
operator + (double d, const Complex& c1) {
    return Complex(c1.real() + d, c1.imag());
}


inline Complex
operator + (const Complex& c) {
    return c;
}

inline Complex
operator - (const Complex& c) {
    return Complex(-c.real(), -c.imag());
}

inline bool
operator == (const Complex& l, const Complex& r) {
    return (l.real() == r.real()) && (l.imag() == r.imag());
}

inline bool
operator != (const Complex& l, const Complex& r) {
    return (l.real() != r.real()) || (l.imag() != r.imag());
}

inline Complex
conj (const Complex& c) {
    return Complex(c.real(), -c.imag());
}

#endif

// main.cpp
#include <iostream>
#include "complex.h"
using namespace std;

int main() {
	Complex c1(2,1);
    Complex c2;
    cout<<c1<<endl;
    cout<<c2<<endl;
    
    c2 = c1 + 5;
    c2 = 7 + c1;
    c2 = c1 + c2;
    c2 += c1;
    c2 += 3;
    cout<<c2<<endl;
    c2 = -c1;

    cout<<(c1 == c2)<<endl;
    cout<<(c1 != c2)<<endl;
    cout<<conj(c2)<<endl;
    return 0;
}

相關文章