天天看点

基于对象设计(一)不含指针的类——复数设计(C++实现)一、头文件的声明及布局二、类的声明三、构造函数四、全局函数五、操作符重载六、完整代码及测试案例

一、头文件的声明及布局

  • 完整代码在文章末尾
#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;
}
           

运行结果:

基于对象设计(一)不含指针的类——复数设计(C++实现)一、头文件的声明及布局二、类的声明三、构造函数四、全局函数五、操作符重载六、完整代码及测试案例

继续阅读