第四周 运算符重载
1.运算符重载的基本概念
2.赋值运算符的重载
3.运算符重载为友元函数
4.运算符重载实例:可变长数组类的实现
5.流插入运算符和流提取运算符的重载
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)重载运算符()、[]、->或者赋值运算符=时,运算符重载函数必须声明为类的成员函数。
一个小结论:前置的++和–效率更快更好,原因是后置的++和–由于返回值要新建一个对象,调用构造函数,会更慢。