《新标准C++程序设计》4.7-4.9(C++学习笔记17)
一、重载类型强制转换运算符
在C++中,类型的名字(包括类的名字)本身也是一种运算符,即类型强制转换运算符。类型强制转换运算符是单目运算符,也可以被重载,但只能重载为成员函数,不能重载为全局函数。经过适当重载后,“(类型名)对象”这个对对象进行类型强制转换的表达式就等价于“对象.operator类型名()”,即变成对运算符函数的调用。
下面的程序对double类型类型强制转换运算符进行了重载。
#include <iostream> 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; //等价于 double n=2+c.operator double() cout << n; //输出 3.2 }
二、重载自增、自减运算符
自增运算符++、自减运算符--有前置/后置之分,为了区分所重载的是前 置运算符还是后置运算符,C++规定:
前置运算符作为一元运算符重载
重载为成员函数:
T & operator++();
T & operator--();
重载为全局函数:
T1 & operator++(T2);
T1 & operator--(T2);
后置运算符作为二元运算符重载,多写一个没用的参数:
重载为成员函数:
T operator++(int);
T operator--(int);
重载为全局函数:
T1 operator++(T2,int );
T1 operator—( T2,int);
但是在没有后置运算符重载而有前置重载的情况下,在vs中,obj++ 也调用前置重载,而dev则令 obj ++ 编译出错
(1)
#include<iostream> using namespace std; int main() { CDemo d(5); cout << (d++ ) << ","; //等价于 d.operator++(0); cout << d << ","; cout << (++d) << ","; //等价于 d.operator++(); cout << d << endl; cout << (d-- ) << ","; //等价于 operator--(d,0); cout << d << ","; cout << (--d) << ","; //等价于 operator--(d); cout << d << endl; return 0; } 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); }; 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);
(2)
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. 重载运算符()、[]、->或者赋值运算符=时,运算符重载函数必须声明为类的成员函数。
Question:
如何区分自增运算符重载的前置形式和后置形式?
A) 重载时,前置形式的函数名是 ++ operator,后置形式的函数名是 operator ++
B) 后置形式比前置形式多一个 int 类型的参数
C) 无法区分,使用时不管前置形式还是后置形式,都调用相同的重载函数
D) 前置形式比后置形式多了一个int类型的参数