第一步:写出防卫式的声明
#ifndef _COMPLEX_ // _COMPLEX_是名称,自行定义
#define _COMPLEX_
...
#endif
第二步:写出class
#ifndef _COMPLEX_
#define _COMPLEX_
class complex
{
...
}; //谨记勿丢分号
#endif
第三步:考虑复数需要的数据
#ifndef _COMPLEX_
#define _COMPLEX_
class complex
{ //数据要放在private下
private:
double re, im;
}; //谨记勿丢分号
#endif
第四步:考虑复数的构造函数
#ifndef _COMPLEX_
#define _COMPLEX_
class complex
{ //任何一个class都要想它的构造函数
//考虑构造函数要不要默认值
//考虑参数传递是pass by value还是pass by reference(这里是pass by value)(这里传double 4个字节效率和引用一样)
public:
complex(double r = 0, double i = 0) : re(r),im(i)//初值列,将实部虚部设为传进来的r和i
{ }
private:
double re, im;
}; //谨记勿丢分号
#endif
第五步:考虑需要哪些操作复数的函数
#ifndef _COMPLEX_
#define _COMPLEX_
class complex
{
public:
complex(double r = 0, double i = 0) : re(r),im(i)
{ }
//设置类似复数的+=操作等等其他操作
//可以将函数设置为成员函数或非成员函数(这里是成员函数,所以写在这个class里面)
//这里函数operator的具体内容没有写出,如果在class外具体写,operator就不是内联函数了
complex& operator += (const complex&);
//取复数实部和虚部的函数
//设计任何一个函数时要考虑后面要不要加const
//如果此函数内不会改动data的话,就应该加const
//这里函数real的内容已经具体写出,所以为内联函数
double real () const {return re;}//此函数只是要获取实部,没有要改动数据,因此此函数应该加const
double imag () const {return im;}
...
private:
double re, im;
}; //谨记勿丢分号
#endif
如果想要直接取得数据,而不通过其他函数,则需要友元
...
private:
double re, im;
friend complex& _doapl(complex*, const complex&);
};
第六步:考虑class本体之外的东西
- 操作符+=的重载,函数的全名complex::operator
- 首先思考参数是什么,+=参数一定有左有右,由于此函数为成员函数,是作用于左边参数的,所以左边就有一个隐藏的参数放进括号里,即这里的函数只需要写右边的参数,参数名为r
- 参数首先考虑传引用这个函数是将右边加到左边,右边的值不变,所以加const
complex::operator += (const complex& r)
- 接下来考虑返回类型(这个函数返回给调用者的类型),将右边加到左边结果为一个复数,此时是否要传引用,
你从这个函数传出去的东西,这个东西如果不是在这个函数本体中创建出来的(local object)不是的话就可以传引用.这里右边加到左边,左边本来就存在,所以它不是local object,因此这里可以传引用(complex&) - 这个函数在class本体之外,加上inline
inline complex&
complex::operator += (const complex& r)
- 接着写出上述函数的内容
inline complex&
complex::operator += (const complex& r)
{ //这里将函数complex::operator的具体内容交由函数doapl写出,所以将参数原封不动的传出去
//函数complex::operator的具体内容也可以直接在这里写出,可能是出于其他考量,转交由doapl函数写出
return _doapl(this,r);
}
inline complex&
_doapl(complex* ths, const complex& r)
{
ths ->re += r.re;//把右边的实部加到左边
ths ->im += r.im;//把右边的虚部加到左边
return *ths; //最后结果在左边
}
inline complex&
complex::operator += (const complex& r)
{
return _doapl(this,r);
}
重载操作符+(在class本体外)
//如果把重载操作符+的函数写入class内,那它只能应付复数加复数的情况
inline complex
operator + (const complex& x, const complex)
{ //两个传入的复数实部虚部对应相加作为新复数的实部虚部
//括号内为临时对象
return complex ( real(x) + real(y),
imag(x) + imag(y) ); //注意这里是分号
}
inline complex
operator + (const complex& x, double y)
{
return complex(real(x) + y, imag(x));
}
inline complex
operator + (double x, const complex& y)
{
return complex(x + real(y), imag(y));
}
重载<<
定义输出复数的格式
#include <iostream.h>
ostream&
operator << (ostream& os, const complex& x)
{
os << '(' << real(x) << ',' << imag(x) << ')';
}
应用
complex c1(9,8);
cout << c1;
//错误:c1 << cout;
cout << c1 << endl;