本文主要根据候捷《面向对象高级开发》课程实现的一个复数类。
所涉及的功能有 加减乘(除法我高中没学过)、以及对应的+=、-=、*=。还有取模、取反、求共轭复数、判断是否相同、输出等。
代码将分模块的进行讲述,不想看可以直接滑到文末。文末会给出完整代码。
初始化
首先,实现的是类的初始化及对其数据成员的访问。
由于访问数据成员并不会修改其相应的值,可以设置为常函数。
class Complex {
public:
Complex(double x, double y) : re(x), im(y){}
Complex() : re(0), im(0){}
double real() const { return re; }
double imag() const { return im; }
private:
double re, im;
};
取模
取模,即输出 r e 2 + i m 2 \sqrt {re^2 +im^2} re2+im2
class Complex {
public:
double length() {
return pow(this->re * this->re + this->im * this->im, 0.5);
}
private:
double re, im;
};
共轭复数
共轭复数,即实部相同,虚部互为相反数。
求共轭复数,并不会改变原复数。故不返回引用类型。
class Complex {
public:
Complex conj() {
return Complex(this->re, -this->im);
}
private:
double re, im;
};
运算符重载
X=
先实现的是在原对象基础上修改的操作,+=,-=,*=。在原对象的基础上与另一个对象进行运算。
根据相关的运算性质,有着如下的代码。
class Complex {
public:
Complex &operator+=(const Complex &c);
Complex &operator-=(const Complex &c);
Complex &operator*=(const Complex &c);
private:
double re, im;
friend Complex &_plus(Complex *, const Complex &);
friend Complex &_minus(Complex *, const Complex &);
friend Complex &_times(Complex *, const Complex &);
};
// +
inline Complex &_plus(Complex *ths, const Complex &c) {
ths->re += c.re;
ths->im += c.im;
return *ths;
}
// += Complex
inline Complex & Complex::operator += (const Complex & c) {
return _plus(this, c);
}
// -
inline Complex &_minus (Complex *ths, const Complex &c) {
ths->re -= c.re;
ths->im -= c.im;
return *ths;
}
// -= Complex
inline Complex & Complex::operator -= (const Complex & c) {
return _minus(this, c);
}
// *
inline Complex &_times(Complex *ths, const Complex &c) {
ths->re = ths->re * c.re - ths->im * c.im;
ths->im = ths->re * c.im + ths->im * c.re;
return *ths;
}
// *= Complex
inline Complex & Complex::operator*=(const Complex & c) {
return _times(this, c);
}
此外,还写出了相应的与纯实数进行运算。(纯实数可以是一个int、double
等基本数据类型,而纯虚数是实部为0的对象,故不重复实现)
class Complex {
public:
template <typename T>
Complex &operator+=(const T num);
template <typename T>
Complex &operator-=(const T num);
template <typename T>
Complex &operator*=(const T num);
private:
double re, im;
};
// += number
template <typename T>
inline Complex & Complex::operator += (const T num) {
this->re += num;
return *this;
}
// -= number
template <typename T>
inline Complex & Complex::operator -= (const T num) {
this->re -= num;
return *this;
}
// *=number
template <typename T>
inline Complex & Complex::operator *= (const T num) {
this->re *= num;
this->im *= num;
return *this;
}
±*
重载完带=
的运算符后,开始重载基本的运算符,定义了三个基本操作 +-*
分别实现两个复数间的+-*
由于在类内部尝试重载时,发生相应的错误(参数个数过多),于是在类的外部定义了相应的功能函数。
在该部分,考虑到运算符左右的参数类型的问题,同样进行了重载。
//Complex + Complex
inline Complex operator+ (const Complex & x,const Complex & y) {
return Complex(x.real() + y.real(), x.imag() + y.imag());
}
// Complex + number
template <typename T>
inline Complex operator+(const Complex &c, T num) {
return Complex(c.real() + num, c.imag());
}
// number + Complex
template <typename T>
inline Complex operator+(T num, const Complex &c) {
return Complex(c.real() + num, c.imag());
}
//Complex - Complex
inline Complex operator-(const Complex &x, const Complex &y) {
return Complex(x.real() - y.real(), x.imag() - y.imag());
}
// Complex - number
template <typename T>
inline Complex operator-(const Complex &c, T num) {
return Complex(c.real() - num, c.imag());
}
// number - Complex
template <typename T>
inline Complex operator-(T num, const Complex &c) {
return Complex(num - c.real(), -c.imag());
}
// Complex * Complex
inline Complex operator*(const Complex &x, const Complex &y) {
return Complex(x.real() * y.real() - x.imag() * y.imag(), x.real() * y.imag() + x.imag() * y.real());
}
// Complex * number
template <typename T>
inline Complex operator*(const Complex &c, T num) {
return Complex(c.real() * num, c.imag() * num);
}
// number * Complex
template <typename T>
inline Complex operator*(T num, const Complex &c) {
return Complex(c.real() * num, c.imag() * num);
}
取反(-X)
私以为取反是用来赋值,故并未修改原对象的成员变量。
// -Complex
inline Complex operator-(const Complex &c) {
return Complex(-c.real(), -c.imag());
}
==(!=)
实部虚部完全相同为相等,任一个不同则为不同。
// ==
inline bool operator==(const Complex &x, const Complex &y) {
return (x.real() == y.real()) && (x.imag() == y.imag());
}
// !=
inline bool operator!=(const Complex &x, const Complex &y) {
// return !(x == y); //不是相同则为不同
return (x.real() != y.real()) || (x.imag() != y.imag());
}
输出
输出的格式为a+b i
,考虑到美观性,额外的判断了下a==0 b==0 b < 0
的情况。即,0+3i、1+0i、1+(-3)i
类型特殊化处理。
inline ostream& operator <<(ostream& os,const Complex & c) {
if (c.real() && c.imag()) {
if (c.imag() >0) {
return os << c.real() << "+" << c.imag() << "i";
} else {
return os << c.real() << c.imag() << "i";
}
} else if (c.real()) {
return os << c.real();
} else {
return os << c.imag() << "i";
}
}
完整代码及部分测试
#include<bits/stdc++.h>
using namespace std;
class Complex {
public:
Complex(double x, double y) : re(x), im(y){}
Complex() : re(0), im(0){}
double real() const { return re; }
double imag() const { return im; }
Complex &operator+=(const Complex &c);
template <typename T>
Complex &operator+=(const T num);
Complex &operator-=(const Complex &c);
template <typename T>
Complex &operator-=(const T num);
Complex &operator*=(const Complex &c);
template <typename T>
Complex &operator*=(const T num);
Complex conj() {
return Complex(this->re, -this->im);
}
double length() {
return pow(this->re * this->re + this->im * this->im, 0.5);
}
private:
double re, im;
friend Complex &_plus(Complex *, const Complex &);
friend Complex &_minus(Complex *, const Complex &);
friend Complex &_times(Complex *, const Complex &);
};
// +
inline Complex &_plus(Complex *ths, const Complex &c) {
ths->re += c.re;
ths->im += c.im;
return *ths;
}
// -
inline Complex &_minus (Complex *ths, const Complex &c) {
ths->re -= c.re;
ths->im -= c.im;
return *ths;
}
// *
inline Complex &_times(Complex *ths, const Complex &c) {
ths->re = ths->re * c.re - ths->im * c.im;
ths->im = ths->re * c.im + ths->im * c.re;
return *ths;
}
// += Complex
inline Complex & Complex::operator += (const Complex & c) {
return _plus(this, c);
}
// += number
template <typename T>
inline Complex & Complex::operator += (const T num) {
this->re += num;
return *this;
}
// -= Complex
inline Complex & Complex::operator -= (const Complex & c) {
return _minus(this, c);
}
// -= number
template <typename T>
inline Complex & Complex::operator -= (const T num) {
this->re -= num;
return *this;
}
// *= Complex
inline Complex & Complex::operator*=(const Complex & c) {
return _times(this, c);
}
// *=number
template <typename T>
inline Complex & Complex::operator *= (const T num) {
this->re *= num;
this->im *= num;
return *this;
}
//Complex + Complex
inline Complex operator+ (const Complex & x,const Complex & y) {
return Complex(x.real() + y.real(), x.imag() + y.imag());
}
// Complex + number
template <typename T>
inline Complex operator+(const Complex &c, T num) {
return Complex(c.real() + num, c.imag());
}
// number + Complex
template <typename T>
inline Complex operator+(T num, const Complex &c) {
return Complex(c.real() + num, c.imag());
}
//Complex - Complex
inline Complex operator-(const Complex &x, const Complex &y) {
return Complex(x.real() - y.real(), x.imag() - y.imag());
}
// Complex - number
template <typename T>
inline Complex operator-(const Complex &c, T num) {
return Complex(c.real() - num, c.imag());
}
// number - Complex
template <typename T>
inline Complex operator-(T num, const Complex &c) {
return Complex(num - c.real(), -c.imag());
}
// -Complex
inline Complex operator-(const Complex &c) {
return Complex(-c.real(), -c.imag());
}
// Complex * Complex
inline Complex operator*(const Complex &x, const Complex &y) {
return Complex(x.real() * y.real() - x.imag() * y.imag(), x.real() * y.imag() + x.imag() * y.real());
}
// Complex * number
template <typename T>
inline Complex operator*(const Complex &c, T num) {
return Complex(c.real() * num, c.imag() * num);
}
// number * Complex
template <typename T>
inline Complex operator*(T num, const Complex &c) {
return Complex(c.real() * num, c.imag() * num);
}
inline ostream& operator <<(ostream& os,const Complex & c) {
if (c.real() && c.imag()) {
if (c.imag() >0) {
return os << c.real() << "+" << c.imag() << "i";
} else {
return os << c.real() << c.imag() << "i";
}
} else if (c.real()) {
return os << c.real();
} else {
return os << c.imag() << "i";
}
}
// ==
inline bool operator==(const Complex &x, const Complex &y) {
return (x.real() == y.real()) && (x.imag() == y.imag());
}
// !=
inline bool operator!=(const Complex &x, const Complex &y) {
// return !(x == y); //不是相同则为不同
return (x.real() != y.real()) || (x.imag() != y.imag());
}
int main() {
Complex x(3,4);
Complex y(3, -4);
cout << x.length() << endl;
cout << x * y << endl;
x += 2;
cout << x << endl;
cout << -x << endl;
cout << (x == y.conj())<<endl;
cout << (x.conj() != y) << endl;
cout << x + y << endl;
cout << 1 + x << endl;
cout << y + 3 << endl;
cout << 2 * x << endl;
return 0;
}