为什么要对运算符进行重载
C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算符进行重新定义,赋予其新的功能,以满足自身的需求。
C++运算符重载的实质
运算符重载的实质就是函数重载或函数多态。运算符重载是一种形式的C++多态。目的在于让人能够用同名的函数来完成不同的基本操作。要重载运算符,需要使用被称为运算符函数的特殊函数形式,运算符函数形式:operatorp(argument-list)//operator 后面的'p'为要重载的运算符符号。
运算符重载的规则
(1)为了防止用户对标准类型进行运算符重载,C++规定重载后的运算符的操作对象必须至少有一个是用户定义的类型
这是什么意思呢?
比如说现在有两个数:int number1,int number2,
那么number1+number2 求的是两个数的和,
但是如果你重载以后让着两个数相加为他们的乘积,这肯定是不合乎逻辑的。
可能重载以后会有二义性,导致程序不知道该执行哪一个(是自带的的还是重载后的函数)
(2)使用运算符不能违法运算符原来的句法规则。如不能将% 重载为一个操作数,
例如:
int index;
%index;这种是不被允许的
(3)不能修改运算符原先的优先级。
(4)不能创建一个新的运算符,例如不能定义operator** (···)来表示求幂
(5)不能进行重载的运算符:成员运算符,作用域运算符,条件运算符,sizeof运算符,typeid(一个RTTI运算符),const_cast、dynamic_cast、reinterpret_cast、
static_cast强制类型转换运算符
(6)大多数运算符可以通过成员函数和非成员函数进行重载但是下面这四种运算符只能通过成函数进行重载:
= 赋值运算符,()函数调用运算符,[ ]下标运算符,->通过指针访问类成员的运算符。
(7)除了上述的规则,其实我们还应该注意在重载运算符的时候遵守一些明智的规则:例如:不要将+运算符重载为交换两个对象的值。
重载运算符的两种形式:
重载运算符有两种方式,即:
重载为类的成员函数||重载为类的非成员函数。
重载为类的非成员函数的时候:
通常我们都将其声明为友元函数,因为大多数时候重载运算符要访问类的私有数据,(当然也可以设置为非友元非类的成员函数。但是非友元又不是类的成员函数是没有办法直接访问类的私有数据的),如果不声明为类的友元函数,而是通过在此函数中调用类的公有函数来访问私有数据会降低性能。所以一般都会设置为类的友元函数,这样我们就可以在此非成员函数中访问类中的数据了。
可以用作重载的运算符
算术运算符:+,-,*,/,%,++,--;
位操作运算符:&,|,~,^,<<,>>
逻辑运算符:!,&&,||;
比较运算符:<,>,>=,<=,==,!=;
赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;
其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。
下列运算符不允许重载:
.,.*,::,?:
代码详解
(重载了基本运算符和<<运算符,后者是为了输出类成员的值。四则运算符提供两种重载,友元函数重载被注释掉了)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
#include<iostream> using namespace std; class A { public: friend ostream& operator<<(ostream& os, const A& app) { os<<app.data; return os; }//次函数用来重载<<运算符使其输出A类的值 A(int d):data(d){} A operator+(A&); A operator-(A&); A operator*(A&); A operator/(A&); A operator%(A&); /* friend A operator+(A&,A&); friend A operator-(A&,A&); friend A operator*(A&,A&); friend A operator/(A&,A&); friend A operator%(A&,A&);*/ private: int data; }; //作为成员函数形式进行重载 A A::operator+(A &a) { return A(data+a.data); } A A::operator-(A &a) { return A(data-a.data); } A A::operator*(A &a) { return A(data*a.data); } A A::operator/(A &a) { return A(data/a.data); } A A::operator%(A &a) { return A(data%a.data); } /* //作为友元函数进行重载 A operator+(A &a1,A &a2) { return A(a1.data+a2.data); } A operator-(A &a1,A &a2) { return A(a1.data+a2.data); } A operator*(A &a1,A &a2) { return A(a1.data+a2.data); } A operator/(A &a1,A &a2) { return A(a1.data+a2.data); } A operator%(A &a1,A &a2) { return A(a1.data+a2.data); } */ int main() { A a1(1),a2(2),a3(3); a1=a2+a3; cout<<a1<<endl; //a1=a2.operator+(a3); //cout<<a1<<endl; } |