一、头文件的声明及布局
- 完整代码在文章末尾
#ifndef XXX
#define XXX
…… // 前置声明(第一板块)
…… // 类的声明(第二板块)
…… // 类的定义(第三板块)
#endif
二、类的声明
- 成员变量:实部,虚部。
private:
double re, im;
- 基本接口:获得实部、虚部。
声明为const是为了使常量对象也能调用该方法。
double real()const { return re; }
double imag()const { return im; }
- 构造函数。
- 成员函数。
三、构造函数
Complex(double r=0,double i=0):
re(r),im(i){ };
- 构造函数提供了默认实参,当创建对象没提供参数时,使用默认实参;提供了参数则使用所提供的参数。
- 构造函数初始值列表是必要的,如果没有构造函数初始值列表,在进入构造函数的函数体之前会进行默认初始化,如果函数体里面有相关语句,这只是赋值语句,并不是初始化,效率稍微差一些。
四、全局函数
- 获得实部和虚部的全局函数
inline
double imag(const Complex& c)
{
return c.imag();
}
inline
double real(const Complex& c)
{
return c.real();
}
- 取得共轭复数的函数
inline
Complex conj(const Complex& c)
{
return Complex(c.real(), -c.imag());
}
- 计算共轭复数的乘积函数
#include<cmath>
inline
double norm(const Complex& c)
{
return pow(c.real(), 2) + pow(c.imag(), 2);
}
五、操作符重载
- 算术运算符的重载一般是通过复合赋值运算符来实现的。
- 复合赋值运算符的重载一般是定义为成员函数,返回所调用对象的引用。
- 一般重载了==运算符就会定义!=运算符。
- 重载的输出运算符必须是全局函数。
1.复合赋值运算符
(1)复合赋值运算符的声明:
Complex& operator+=(const Complex&);
Complex& operator-=(const Complex&);
Complex& operator/=(const Complex&);
Complex& operator*=(const Complex&);
(2)复合赋值运算符的类外实现:
- 类中的成员函数自动被声明为inline的,如果函数的实现在类外,需要自己声明上inline。
- 相同class的各个object互为友元,所以下列函数可以直接访问形参c的私有成员。
//+=
inline
Complex& Complex::operator+=(const Complex& c)
{
this->re += c.re;
this->im += c.im;
return *this;
}
//-=
inline
Complex& Complex::operator-=(const Complex& c)
{
this->re -= c.re;
this->im -= c.im;
return *this;
}
//*=
inline
Complex& Complex::operator*=(const Complex& c)
{
this->re = this->re * c.re - this->im * c.im;
this->im = this->re * c.im + this->im * c.re;
return *this;
}
// /=
inline
Complex& Complex::operator/=(const Complex& c)
{
double tmp = norm(c);
*this *= conj(c);
this->re /= tmp;
this->im /= tmp;
return *this;
}
2.算术运算符
//复数与实数四则运算
//加法
inline
Complex operator+(const Complex& c, double x)
{
return Complex(real(c) + x, imag(c));
}
inline
Complex operator+(double x, const Complex& c)
{
return Complex(x + real(c), imag(c));
}
//减法
inline
Complex operator-(const Complex& c, double x)
{
return Complex(real(c) - x, imag(c));
}
inline
Complex operator-(double x, const Complex& c)
{
return Complex(x - real(c), imag(c));
}
//乘法
inline
Complex operator*(const Complex& c, double x)
{
return Complex(real(c) * x, imag(c) * x);
}
inline
Complex operator*(double x, const Complex& c)
{
return Complex(x * real(c), x * imag(c));
}
//除法
inline
Complex operator/(const Complex& c, double x)
{
return Complex(real(c) / x, imag(c) / x);
}
3.相等运算符
//相等运算符
bool operator==(const Complex& c1, const Complex& c2)
{
return real(c1) == real(c2) && imag(c1) == imag(c2);
}
bool operator!=(const Complex& c1, const Complex& c2)
{
return !(c1 == c2);
}
4.输出运算符
ostream& operator<<(ostream& os, const Complex& c)
{
return os << "(" << real(c) << "," << imag(c) << ")";
}
六、完整代码及测试案例
1.头文件
#pragma once
#ifndef _MY_COMPLEX_
#define _MY_COMPLEX_
class Complex
{
public:
Complex(double r,double i):
re(r),im(i){ };
double real()const { return re; }
double imag()const { return im; }
Complex& operator+=(const Complex&);
Complex& operator-=(const Complex&);
Complex& operator*=(const Complex&);
Complex& operator/=(const Complex&);
private:
double re, im;
};
//实部和虚部
inline
double imag(const Complex& c)
{
return c.imag();
}
inline
double real(const Complex& c)
{
return c.real();
}
//conjugate
inline
Complex conj(const Complex& c)
{
return Complex(c.real(), -c.imag());
}
//norm
#include<cmath>
inline
double norm(const Complex& c)
{
return pow(c.real(), 2) + pow(c.imag(), 2);
}
//+=
inline
Complex& Complex::operator+=(const Complex& c)
{
this->re += c.re;
this->im += c.im;
return *this;
}
//-=
inline
Complex& Complex::operator-=(const Complex& c)
{
this->re -= c.re;
this->im -= c.im;
return *this;
}
//*=
inline
Complex& Complex::operator*=(const Complex& c)
{
this->re = this->re * c.re - this->im * c.im;
this->im = this->re * c.im + this->im * c.re;
return *this;
}
// /=
inline
Complex& Complex::operator/=(const Complex& c)
{
double tmp = norm(c);
*this *= conj(c);
this->re /= tmp;
this->im /= tmp;
return *this;
}
//复数与复数四则运算
inline
Complex operator+(const Complex& c1, const Complex& c2)
{
return Complex(real(c1) + real(c2), imag(c1) + imag(c2));
}
inline
Complex operator-(const Complex& c1, const Complex& c2)
{
return Complex(real(c1) - real(c2), imag(c1) - imag(c2));
}
inline
Complex operator*(const Complex& c1, const Complex& c2)
{
return Complex(real(c1) * real(c2) - imag(c1) * imag(c2),
real(c1) * imag(c2) + imag(c1) * real(c2));
}
inline
Complex operator/(const Complex& c1, const Complex& c2)
{
Complex res = c1;
return (res /= c2);
}
//复数与实数四则运算
//加法
inline
Complex operator+(const Complex& c, double x)
{
return Complex(real(c) + x, imag(c));
}
inline
Complex operator+(double x, const Complex& c)
{
return Complex(x + real(c), imag(c));
}
//减法
inline
Complex operator-(const Complex& c, double x)
{
return Complex(real(c) - x, imag(c));
}
inline
Complex operator-(double x, const Complex& c)
{
return Complex(x - real(c), imag(c));
}
//乘法
inline
Complex operator*(const Complex& c, double x)
{
return Complex(real(c) * x, imag(c) * x);
}
inline
Complex operator*(double x, const Complex& c)
{
return Complex(x * real(c), x * imag(c));
}
//除法
inline
Complex operator/(const Complex& c, double x)
{
return Complex(real(c) / x, imag(c) / x);
}
//相等运算符
bool operator==(const Complex& c1, const Complex& c2)
{
return real(c1) == real(c2) && imag(c1) == imag(c2);
}
bool operator!=(const Complex& c1, const Complex& c2)
{
return !(c1 == c2);
}
#endif // !_MY_COMPLEX_
2.主程序
#include<iostream>
using namespace std;
#include"complex.h"
ostream& operator<<(ostream& os, const Complex& c)
{
return os << "(" << real(c) << "," << imag(c) << ")";
}
int main()
{
Complex c1(2, 1);
Complex c2(4, 0);
cout << c1 << endl;
cout << c2 << endl;
cout << conj(c1) << endl;
cout << norm(c1) << endl;
cout << (c1 += c2) << endl;
cout << (c1 -= c2) << endl; //先加再减值不变
cout << (c1 *= c2) << endl;
cout << (c1 /= c2) << endl; //先乘再除值不变
cout << c1 + c2 << endl;
cout << c1 - c2 << endl;
cout << c1 * c2 << endl;
cout << c1 / c2 << endl;
cout << (c2 + 2) << endl;
cout << (c2 - 2) << endl;
cout << (c2 * 2) << endl;
cout << (c2 / 2) << endl;
cout << (5 + c1) << endl;
cout << (5 - c1) << endl;
cout << (5 * c1) << endl;
cout << (c1 == c2) << endl;
cout << (c1 != c2) << endl;
system("pause");
return 0;
}
运行结果: