一.运算符重载
1.语法形式
返回值类型 operator 运算符符号 (形参列表)
{
函数体
}
eg:
Demo operator +(Demo &obja, Demo &objb)//重载+运算符
{
}
2.注意
1)可以被重载的运算符:
算术运算符:+、-、*、/、%、++、--
位操作运算符:&、|、~、^(位异或)、<<(左移)、>>(右移)
逻辑运算符:!、&&、||
比较运算符:<、>、>=、<=、==、!=
赋值运算符:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
其他运算符:[]、()、->、,、new、delete、new[]、delete[]
2)不被重载的运算符:
. ?: sizeof :: *
逗号“.”、?号表达式“? :”、sizeof、作用域“::”、指针运算符“*”
二.友元运算符重载
1.理解
运算符重载作为类的友元
2.语法形式
class 类名{
....
friend 返回值类型 operator 运算符符号 (形参列表);
};
返回值类型 operator 运算符符号 (形参列表)
{
函数体
}
eg:
class Demo{
public:
Demo(int val = 0) : val(val)
{
cout << __func__ << ":" << __LINE__ << endl;
}
~Demo()
{
cout << __func__ << ":" << __LINE__ << endl;
}
void setval(int val)
{
this->val = val;
}
int getval() const
{
return this->val;
}
friend Demo operator +(Demo &, Demo &);//友元运算符重载
friend Demo & operator ++(Demo &);
friend Demo operator ++(Demo &,int );
friend Demo operator << (Demo &, int);
private:
int val;
};
//+运算符重载
Demo operator +(Demo &obja, Demo &objb)
{
cout << __func__ << ":" << __LINE__ << endl;
Demo c(obja.val+objb.val);
return c;
}
//前++运算符重载
Demo & operator ++(Demo &obj)
{
++(obj.val);
return obj;
}
//后++运算符重载
Demo operator ++(Demo &obj,int val)
{
Demo temp(obj.val++);
return temp;
}
// <<运算符重载
Demo operator << (Demo &obj, int bits)
{
#if 0
Demo tmp(obj.val << bits);
return tmp;
#else
return Demo(obj.val << bits);//临时对象表示
#endif
}
int main()
{
Demo a(333);
Demo b(333);
Demo obj(3);
Demo c = a+b;//等价: Demo c = operator +(a,b);
cout << c.getval() << endl;
++a;//等价: operator ++ (a);
cout << a.getval() << endl;
Demo d = b++;//等价:Demo d = operator ++(b,1);
cout << b.getval() << endl;
cout << d.getval() << endl;
Demo tem = obj << 2;
cout << obj.getval() << endl;
cout << tem.getval() << endl;
return 0;
}
三.成员运算符重载
1.理解
指运算符重载为类的成员函数
2.语法形式
class 类名{
....
返回值类型 operator 运算符符号 (形参列表)
};
返回值类型 类名::operator 运算符符号 (形参列表)
{
函数体
}
eg:
class Demo{
public:
Demo(int val = 0) : val(val)
{
cout << __func__ << ":" << __LINE__ << endl;
}
~Demo()
{
cout << __func__ << ":" << __LINE__ << endl;
}
void setval(int val)
{
this->val = val;
}
int getval() const
{
return this->val;
}
Demo operator +(Demo &);//成员运算符重载
private:
int val;
};
//+运算符重载
Demo Demo::operator +(Demo &obj)
{
cout << __func__ << ":" << __LINE__ << endl;
Demo c(this->val+obj.val);
return c;
}
int main()
{
Demo a(333);
Demo b(333);
Demo c = a+b;//等价:Demo c = a.operator +(b)
cout << c.getval() << endl;
return 0;
}
四、运算符重载的注意事项
A、除关系运算符"."、成员指针运算符".*"、作用域运算符"::"、sizeof运算符和三目运算符"?:"以外,C++中的所有运算符都可以重载(其中“=”和“&”不必用户重载)
B、重载运算符限制在C++语言中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符
C、运算符重载的实质是函数重载,遵循函数重载的选择原则
D、重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构
E、运算符重载不能改变该运算符用于内部类型对象的含义
F、运算符重载是针对新类型数据的实际需要对原有运算符进行的适当的改造,重载的功能应当与原有功能相类似,避免没有目的地使用重载运算符
G、重载运算符的函数不能有默认的参数,否则就改变了运算符的参数个数
H、重载的运算符只能是用户自定义类型,否则就不是重载而是改变了现有的C++标准数据类型的运算符的规则
I、运算符重载可以通过成员函数的形式,也可是通过友元函数,非成员非友元的普通函数。