中国大学MOOC程序设计与算法(三):C++ 面向对象程序设计 第四周 运算符重载 笔记 之

第四周 运算符重载
1.运算符重载的基本概念
2.赋值运算符的重载
3.运算符重载为友元函数
4.运算符重载实例:可变长数组类的实现
5.流插入运算符和流提取运算符的重载
6.类型转换运算符、自增自减运算符的重载

6.类型转换运算符、自增自减运算符的重载

重载类型转换运算符:把对象转换成另一种类型
类型转换运算符重载时函数返回值是不用写的,默认就是这个类型本身。

#include 
using namespace std;
class Complex
{
	double real,imag;
public:
	Complex(double r=0,double i=0):real(r),imag(i) { };
	operator double () { return real; }
	// 重载强制类型转换运算符 double
};
int main()
{
	Complex c(1.2,3.4);
	cout << (double)c << endl; //出 输出 1.2
	double n = 2 + c; //c被自动转换成double了,正好定义了double的重载,现在就等价于 double n=2+c.operator double()
	cout << n; //出 输出 3.2
}

重载自增,自减运算符

自增运算符++、自减运算符–有前置/后置之分,为了区分所重载的是前置运算符还是后置运算符,C++规定:
1)前置运算符作为一元运算符重载
重载为成员函数:
T & operator++();
T & operator–();
重载为全局函数:
T1 & operator++(T2);
T1 & operator—(T2);
2)后置运算符作为二元运算符重载,多写一个没用的参数:
重载为成员函数:
T operator++(int);
T operator–(int);
重载为全局函数:
T1 operator++(T2,int );
T1 operator—( T2,int);
但是在没有后置运算符重载而有前置重载的情况下,在vs中,obj++ 也调用前置重载,而dev则令 obj ++ 编译出错。

例子:

int main()
{
	CDemo d(5);
	cout << (d++ ) << ","; //等价于 d.operator++(0);//0是没用的参数
	cout << d << ",";//这里要么需要重载<<,要么就定义一个类型转换d
	cout << (++d) << ","; //等价于 d.operator++();
	cout << d << endl;
	cout << (d-- ) << ","; //等价于 operator--(d,0);
	cout << d << ",";
	cout << (--d) << ","; //等价于 operator--(d);
	cout << d << endl;
	return 0;
}

输出结果:
5,6,7,7
7,6,5,5
如何编写 CDemo?

class CDemo {
	private :
		int n;
	public:
		CDemo(int i=0):n(i) { }
		CDemo & operator++(); // 用于前置形式
		CDemo operator++( int ); // 用于后置形式
		operator int ( ) { return n; }
		friend CDemo & operator--(CDemo & );
		friend CDemo operator--(CDemo & ,int);
};
//C++里面,++a返回的是a的引用,是支持(++a)=1;操作的。而a++返回的只是a改变之前的值
CDemo & CDemo::operator++()
{
	 //前置 ++
	n ++;
	return * this;
} // ++s即为: s.operator++();
CDemo CDemo::operator++( int k )
{
	 //后置 ++
	CDemo tmp(*this); // 记录修改前的对象
	n ++;
	return tmp; // 返回修改前的对象
} // s++即为: s.operator++(0);
CDemo & operator--(CDemo & d)
{
	// 前置--
	d.n--;
	return d;
} //--s即为: operator--(s);
CDemo operator--(CDemo & d,int)
{
	// 后置--
	CDemo tmp(d);
	d.n --;
	return tmp;
} //s--即为: operator--(s, 0);
operator int ( ) { return n; }

这里,int 作为一个类型强制转换运算符被重载, 此后
Demo s;
(int) s ; //于 等效于 s.int();
类型强制转换运算符被重载时不能写返回值类型,实际上其返回值类型就是该类型强制转换运算符代表的类型

运算符重载的注意事项
1)C++不允许定义新的运算符 ;
2)重载后运算符的含义应该符合日常习惯;
complex_a + complex_b
word_a > word_b
date_b = date_a + n
3)运算符重载不改变运算符的优先级;
4)以下运算符不能被重载:“.”、“.*”、“::”、“?:”、sizeof;
5)重载运算符()、[]、->或者赋值运算符=时,运算符重载函数必须声明为类的成员函数。

一个小结论:前置的++和–效率更快更好,原因是后置的++和–由于返回值要新建一个对象,调用构造函数,会更慢。

你可能感兴趣的:(中国大学MOOC程序设计与算法(三):C++ 面向对象程序设计 第四周 运算符重载 笔记 之)