C++基础--complex(复数)类的设计过程与思考总结

项目

1.设计complex(复数类)

​ 需求:1)实部,虚部re,im

​ 2)重写+=符号,调用friend_doapl函数,对两个复数进行相加 其中+=函数调用一个全局函数_doapl(complex*,complext&)进行处理。这里只用完成两个复数的相加

​ 3)重写+符号,这里只用完成两个复数,复数和实数的相加

设计完成后的代码

#ifndef __MYCOMPLEX__

#define __MYCOMPLEX__

class complex;

complex&

__doapl(complex* ths, const complex& r);

complex&

__doami(complex* ths, const complex& r);

complex&

__doaml(complex* ths, const complex& r);

class complex

{

public:

complex(double r = 0, double i = 0) : re(r), im(i) { }

complex& operator += (const complex&);

double real() const { return re; }

double imag() const { return im; }

private:

double re, im;

friend complex& __doapl(complex*, const complex&);

};

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);

}

inline double

imag(const complex& x)

{

return x.imag();

}

inline double

real(const complex& x)

{

return x.real();

}

inline complex

operator + (const complex& x, const complex& y)

{

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));

}

endif //MYCOMPLEX

设计:

1)确定成员变量以及get方法 思考函数const,real()和img需要加,因为不需要修改值。

2)确定重载符号operator +=方法。

complex& operator +=(const complex&);

​ 思考返回值是什么类型。我们在复数类计算时,经常 x+=y,等价于x = x+y. 因此,确定返回的是原来的x的值,也就是this。我们可以得出,直接传回引用,因为我们传回去得并不是local variable。但为什么我们不设计是void类型呢?因为当我们计算x+=y的时候,我们可以直接通过引用改变x的值呀?

就比如:

complex& operator +=(const complex& c){

this.re = this.re+c.real();

}

原因就在于,在c++中可以连续复制,如 x1+=x2+=x3; 当发生这种情况的时候,引用必须返回以供作为右值以供下一次的运算。

思考形式参数。能用引用得就用引用。且原值能不能修改呢? x = x+y this指的是x的数据,形式参数指的是y的数据。x的数据发生了改变,但是y的没有。所以我们得出,形式参数要加上const。

3)全局函数_doapl(complex&,complext&)

​ 可能是因为其他地方也要用到,所以就把它写成了全局函数而不是成员函数。为了实现 operator+=调用它,我们得将它声明为一个友元。

​ 其成员变量两个一个是complex*而非complex&的原因是,要传入this,与operator+=发生联动。

4)设计 operator+重载

​ 思考返回值类型,假设有 x3 = x1+x2。x3必然是在函数内新建一个变量并返回,所以不能返回一个局部变量的引用。只能使用值传递。

​ 此外,我们可以注意到,operator+定义在了类外,因为它不需要this这个变量,且operator+二目运算符只允许有两个参数,要想不加入this(类内函数默认添加this形式参数),只能写在类外作为成员函数。

​ 那还有几个问题,复数相加有很多种可能,以下是应该考虑的可能性,我们必须根据这些可能性设计函数的重载:

/**

有三种情况

1.复数加复数

2.复数+double

3.double+复数

**/

inline complex

operator + (const complex& x, const complex& y)

{

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));

}

从complex得到的经验

1)若方法不需要修改数据,一定加上const,因为const对象只能调用const方法。若方法不加const,const对象功能不全。

  1. 形式参数都应该传递引用,如果不需要修改,则一定加上const,否则原值可能被修改。若直接传递了值,则发生复制,会很慢。当然,char这种一个字节的参数可以传值。

3)返回值也尽量用引用传递,快。但是一定不能返回局部变量的引用,因为局部变量存在栈中,方法执行完之后内存就被回收了。

4)简单的函数要加inline即使编译器会自动选择。

5).h文件的划分

C++基础--complex(复数)类的设计过程与思考总结

其中,类声明里的函数不用写具体的形式参数,只用写形式参数的类型即可。简单的函数可以在类声明部分就定义如 real()和Img()。复杂的应该在函数体外进行定义。最后,类内的函数均会自动加上inline,在类外定义的函数若比较简单,应该手动建议编译器使用inlien.

6)操作符重载时,若是双目运算符 如 + 则应该定义为全局函数。

如z = x+y。使用+号时,不需要this的值。

与之相对的是单目运算符,如==或+=

如判断 z==y 的时候,我们需要用到z的值,所以必须定义在类内,所以就没有意义了

7)在函数声明阶段,复杂的函数不用写函数体,也不用写具体的形式参数,只用写形式参数的类型。

如:

complex&

operator +=(const complex&); //不需要写成(const complex&r)

,只写函数名。

但简单的如real()可以写完函数体。复杂的函数应该在类定义区域完成函数体的编写。

以上是 C++基础--complex(复数)类的设计过程与思考总结 的全部内容, 来源链接: utcz.com/a/72696.html

回到顶部