【C++之多态性】运算符重载


什么是运算符重载:对已有的运算符赋予多重含义
实现机制:
1、将制定的运算符表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参;
2、编译系统对重载运算符的选择,遵循函数重载的选择选择原则;
规则和限制:
1、不可以重载的运算:"." “.*” “::” “?:”
2、只能重载C++语言中已有的运算符,不可臆造新的
3、不改变原运算符的优先级和结合性
4、不能改变操作数个数;
5、经重载的运算符,其操作数中至少应该有一个是自定义类型
两种形式:
1、重载为类的非静态成员函数
2、重载为非成员函数(通常为友元函数)
声明形式: 函数类型 operator 运算符(形参){}
其中参数个数要求为:
1、重载为类成员函数时:参数个数=原操作数个数-1(除了后置++或–之外)(减1的原因是对象本身就是另一个操作数)
2、重载为非成员函数时,参数个数=原操作数个数,且至少应该有一个自定义类型的形参

运算符成员函数的设计

1、双目运算符B:

  • 如果要重载运算符B为类成员函数,使之能够实现表达式 oprd1 B oprd2,其中oprd1为A类对象,则B为应被重载为A类的成员函数,形参类型应该是oprd2所属的类型
  • 经重载后,表达式oprd1 B oprd2相当于oprd1.operator B(oprd2)

如下举例所示,设计一个复数相加的程序,

class Complex {
public:
	Complex(int _real, int _imag) :real(_real), imag(_imag) {};
	Complex& operator + (const Complex& c) {
		real += c.real;
		imag += c.imag;
		return *this;
	}
	int getReal() {
		return real;
	}
	int getImag() {
		return imag;
	}
private:
	int real;//实部
	int imag;//虚部
};

int main() {
	Complex c1(1, 1);
	Complex c2(2, 2);
	c1 = c1 + c2;
	printf("c1的虚数为:%d + %dj", c1.getReal(), c1.getImag());
}

2、单目运算符U:

  • 如果要重载U为类成员函数,使之能够实现表达式U oprd,其中oprd为A类的对象,则U应被重载为A类的成员函数,无形参
  • 重载后,表达式U oprd相当于 oprd.operator U()

3、后置单目运算符++和–

  • 如果要重载后置运算符++和–为类成员函数,使之能够实现表达式oprd++oprd--,其中oprd为A类对象,则++或–应被重载为A类的成员函数且有一个int型形参(主要是用来区别于前置++或–,不必写形参名)
  • 经重载后,表达式oprd++相当于oprd.operator ++ (0);

举例如下,实现复数的实部和虚部自加

class Complex {
public:
	Complex(int _real, int _imag) :real(_real), imag(_imag) {};
	Complex& operator ++ () {
		++real;
		++imag;
		return *this;
	}
	Complex operator ++ (int) {
		Complex old = *this;
		++(*this);
		return old;
	}
	void showComplex() {
		printf("%d + %dj\n", real, imag);
	}
private:
	int real;//实部
	int imag;//虚部
};

int main() {
	Complex c1(1, 1);
	(++c1).showComplex();
	(c1++).showComplex();
	c1.showComplex();
}
/*输出:
2 + 2j
2 + 2j
3 + 3j
*/

从输出结果可以看出,复数的前置++和后置++都运行正确;

运算符非成员函数的设计

注意:
1、函数的形参代表依自左至右次序排列的各操作数;
2、后置单目运算符++和–的重载函数,形参列表要增加一个int,但不必写形参名
3、如果在运算符的重载函数中需要操作某类对象的私有成员,可以将此函数的声明为该类的友元。
运算符非成员函数:
1、双目运算符 B重载后,
表达式:oprd1 B oprd2 等同于 operator B(oprd1, oprd2)
前置单目运算符 B 重载后
表达式:B oprd 等同于 operator B(oprd)
后置单目运算符++和–重载后
表达式:oprd++ 等同于 operator ++(oprd, 0)
举例如下:实现复数的连续输出

class Complex {
public:
	Complex(int _real, int _imag) :real(_real), imag(_imag) {};
	friend ostream& operator << (ostream& out, const Complex& c);
private:
	int real;//实部
	int imag;//虚部
};

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

int main() {
	Complex c1(1, 1);
	Complex c2(2, 2);
	Complex c3(3, 3);
	cout << c1 << c2 << c3;
}
/*输出:
1 + 1j 2 + 2j 3 + 3j
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值