第八章8.2.4

2 篇文章 0 订阅
1 篇文章 0 订阅

标题Part4 【运算符重载为非成员函数】

将运算符重载为类外的非成员函数。当要将运算符重载为类的成员函数的时候,他的左操作数必须是这个类的对象。

Case1:如果我们面临的运算,他的左操作数,不是类的对象,比如是我们要实现一个实数加复数,实数在加号左边,那么是否还可以通过重载成员函数解决这个问题吗?那就不行了。这个时候我们就要将这个运算符重载为类外的一个普通的全局函数。
Case2:虽然说,一个运算符的左操作数是类的对象,但是这个类不是由我们自己定义的,比如说是类库里面现成的类的对象。那么这个类也不由我们自己设计,我们也没有权力去给这个类增加一个什么重载运算符函数。那么这个时候,如果我们要想能够让个对象跟我们自定义的另外一个类的对象去运算的话,我们就只能将运算符重载为类外的非成员函数。

运算符重载为类外的非成员函数的规则
函数的形参代表依左到右依次序排列的各操作数。(形参要列出所有的操作数,比如二元运算符、他的形参就应该是两个操作数)
重载为非成员函数时
 参数个数=原操作数个数(后置++、- -除外)
 至少应该有一个自定义类型的参数(不能两个参数都是基本数据类型的,比如我们重载一个函数,把整数的加法定义修改一下,这是不可以的,所以只能是为自定义类型去扩展,去重新定义,这个已有的运算符,不可以修改原有的运算含义)。
解释:重载为非成员函数时,后置的++or—除了他要有一个形参作为参与运算的对象以外,还要增加一个整数,以区分前置后后置的单目运算符。
 后置单目运算符 ++和- -的重载函数,形参列表中要增加一个int,但不必写形参名。
 如果在运算符的重载函数中需要操作某类对象的私有成员,可以将这个函数声明为该类的友元。(通过类的公有接口去访问私有数据也是可以的。但是友员的效率要高些)

运算符重载为非成员函数的规则
 双目运算符 B重载后、
表达式 oprd1 B oprd2 等同于 operator B(oprd1,oprd2)
 前置单目运算符B重载后,
表达式 B oprd 等同于 operator B(oprd)
 后置单目运算符 ++和 - -重载后,
表达式 oprd B 等同于 operator B(oprd,0) O在函数中提不可使用,他只是一个记号。
这里的operator是全局函数。
例题解析前奏:以非成员函数的形式为复数类重载加法、减法运算。并且还为它重载一个插入运算符。这样的话了,我们就可以用“cout“整个输出一个复数对象了。重载插入运算符就是只能重载为类外的成员函数,因为他的左操作数虽然是一个类的对象,但是它是系统里面预定义好的,这个类库里面的一个输出流类的对象。Cout不是我们程序员自定义的对象。那这个时候我们就无法在类库里面,这个输出流类里面去加一个重载运算符函数,这个没有权限去加的。所以了,我们就把他重载为类外的非成员函数。实现对于复数对象的整体输出功能。
例题:重载complex的加减法和“<<”运算符为非成员函数。
 将+、-(双目)重载为非成员函数,并将其声明为复数类的友元,两个操作数都是复数类的常引用。(当然也可以是复数类的对象,但是传引用比传对象,效率要高一些,但是传引用就有可能实现双向传递,这会有改变运算的值,这就不是我们希望的结果。所以我们这里传引用,但是加一个const来修饰,传常引用,来保证安全性。)
 将<<(双目)(<<是插入运算符)重载为非成员函数,并将声明为复数类的友元(这样运算效率高),它的左操作数是std::ostream引用,右操作数为复数类的常引用,返回std::ostream引用,用以支持下面形式的输出:cout<< a <<b;
 该输出调用的是:operator<<(operator<<(cout,a),b);

#include<iostream>
using namespace std;

class Complex {
public:
	Complex(double r = 0.0, double i = 0.0) :real(r), image(i) {}//将加法和减法和插入运算符函数都重载为类外的全局函数
	friend Complex operator + (const Complex& c1, const Complex& c2);
	friend Complex operator - (const Complex& c1, const Complex& c2);
	friend ostream& operator << (ostream& out, const Complex& c);
private:
	double real;
	double image;
};

//这几个函数都是普通类外的函数,不在是类的成员函数
Complex operator + (const Complex& c1, const Complex& c2) {
	return Complex(c1.real + c2.real, c1.image + c2.image);
}


Complex operator - (const Complex& c1, const Complex& c2) {
	return Complex(c1.real - c2.real, c1.image - c2.image);
}

ostream& operator<<(ostream & out, const Complex & c) {
	out << "(" << c.real << "," << c.image << ")";
	return out;
}


int main() {
	Complex c1(5, 4), c2(2, 10), c3;
	cout << "c1=" << c1 << endl;
	cout << "c2=" << c2 << endl;
	c3 = c1 - c2;
	cout << "c3=c1-c2=" << c3 << endl;
	c3 = c1 + c2;
	cout << "c3=c1+c2=" << c3 << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值