残局

不过在等杀死希望的最后一刀

0%

复数类

本文主要根据候捷《面向对象高级开发》课程实现的一个复数类。所涉及的功能有 加减乘(除法我高中没学过)、以及对应的+=、-=、*=。还有取模、取反、求共轭复数、判断是否相同、输出等。代码将分模块的进行讲述,不想看可以直接滑到文末。文末会给出完整代码。

初始化

首先,实现的是类的初始化及对其数据成员的访问。
由于访问数据成员并不会修改其相应的值,可以设置为常函数。

1
2
3
4
5
6
7
8
9
10
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;
};

取模

取模,即输出 re2+im2

1
2
3
4
5
6
7
8
class Complex {
public:
double length() {
return pow(this->re * this->re + this->im * this->im, 0.5);
}
private:
double re, im;
};

共轭复数

共轭复数,即实部相同,虚部互为相反数。
求共轭复数,并不会改变原复数。故不返回引用类型。

1
2
3
4
5
6
7
8
class Complex {
public:
Complex conj() {
return Complex(this->re, -this->im);
}
private:
double re, im;
};

运算符重载

X=

先实现的是在原对象基础上修改的操作,+=,-=,*=。在原对象的基础上与另一个对象进行运算。
根据相关的运算性质,有着如下的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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的对象,故不重复实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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;
}

+-*

重载完带=的运算符后,开始重载基本的运算符,定义了三个基本操作 +-*分别实现两个复数间的+-*
由于在类内部尝试重载时,发生相应的错误(参数个数过多),于是在类的外部定义了相应的功能函数。
在该部分,考虑到运算符左右的参数类型的问题,同样进行了重载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//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)

私以为取反是用来赋值,故并未修改原对象的成员变量。

1
2
3
4
// -Complex
inline Complex operator-(const Complex &c) {
return Complex(-c.real(), -c.imag());
}

==(!=)

实部虚部完全相同为相等,任一个不同则为不同。

1
2
3
4
5
6
7
8
9
// ==
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类型特殊化处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
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";
}
}

完整代码及部分测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#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;
}
-------------感谢阅读有缘再见-------------