[3]面向对象程序设计(Object oriented programming):操作符重载与临时对象

2022/2/21 20:35:40

本文主要是介绍[3]面向对象程序设计(Object oriented programming):操作符重载与临时对象,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

第五节 操作符与运算符重载

在C++中,操作符本身就是一种函数,是可以让使用者自定义的。那么我们认为复数的计算,不如直接用+号来使用,而+号的概念和运算规则需要进行运算符重载。

操作符重载根据成员函数的区别有两种写法:

inline complex&
complex::operator += (const complex& r)
{
    return _doapl (this, r);
}

inline complex& //这后面写的是接收者将以怎样的形式得到返回值。
complex::operator +=(this,const comp)
{
    return _doapl (this, r);
}

在复数的class里面,定义出来一个操作符重载的成员函数。

所有的成员函数都带着一个隐藏的参数,这个参数叫this。谁调用这个函数的本身,调用者,就是this。this可以看作被操作的一个类的元素,指向被操作的类元素的地址。

第二种写的,this可以放在前面可以放在后面。

另外,this不能在参数列写出来,可是能够在函数里面用。

所有的二元运算符,都可以将右边的元素加到左边去,然后左边的类有一个this的指针可以完成传址调用。

关于return by reference的语法分析:

传递者无需知道接收者是以reference形式接收。

第一种,成员函数的版本:

inline complex& //这里指接收端是以reference的方式接受
_doapl(complex* ths, const complex& r)
{
    ...
    return *ths;
}

这里传入者直到传入数据的形式是引用reference,而返回值的类型是*ths的一个解引用形式。

事实上,如果只用+=赋值,那么可以写成inline void...而实际上会涉及到一些奇怪的写法,如:

c1 += c2 += c3;则需要有具体的返回数据,写成inline complex&标准。

第二种:非成员函数的版本:

inline double
real(const complex& x)
{
    return x.real();
}

inline double
imag(const complex& x)
{
    return x.imag();
}

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(real(y) + x , imag(y));
}

+号有三种应对方式。可能复数+复数,复数+实数,实数+复数....

临时对象(temp object)

上述函数返回的并不是reference,因为,他们返回的必定是个local object.产生的是一个临时局部变量,所以不能用引用来实现。

typename() 类直接加小括号,类似于变量的声明,相当于根据后续的数据创建临时对象。

complex (a , b) 创建临时的复数变量a + bi ,临时变量的生命只存在于下一行。

class body之外的各种定义:

inline complex
operator + (const complex& x)
{
    return x;
}

inline complex
operator - (const complex& x)
{
    return complex(-real(x) , -imag(x));
}

这两个符号是取反、取正的符号,定义的是一元运算符。靠参数的个数区别二元操作符+

而取正是本身,取反会创建一个新的对象,所以取负操作必须传递一个value。

inline bool
operator == (const complex& x, const complex& y)
{
    return (x.real() == y.real()) && (x.imag() == y.imag());
}

inline bool
operator == (const complex& x,double y)
{
    return (x.imag() == 0) && (x.real() == y);
}

inline bool 
operator == (double x, const complex& y)
{
    return (x == y.real()) && (y.real() == 0);
}

这是比较两个复数是否相等,需要考虑所有的情况。

inline complex
conj (const complex& x)
{
    return complex(real(x), -imag(x));
}

共轭复数。实部相等虚部相反。

#include <iostream.h>
ostream&
operator << (ostream& os,const complex& x)
{
    return os << '(' << real(x) << ',' << imag(x) << ')';
}

complex c1(2,1);
cout << conj(c1);

而在输出的时候,同样需要重载左移运算符。由于左值运算,而cout对应的类为ostream,u送一我们需要提供ostream的引用os。然后才可以进行输出。同样的,在对os左移的时候,实际上改变了这个输出流,所以不需要加const来修饰。

不可以将osteram&改为void,因为可能会遇到连续左移的操作,在输出一个变量的时候,还是需要维护一个ostream类。所以返回类型应当是ostream&

因此,在设计类的时候,一定要考虑使用者是如何使用的。



这篇关于[3]面向对象程序设计(Object oriented programming):操作符重载与临时对象的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程