运算符重载
语法
在类的public中声明,格式: 返回值 operator运算符(参数),定义和性质可看作类的公有函数。
识别匹配
分为双目运算符和单目运算符
双目运算符:两个操作数,如a+b,a和b为+的两个操作数
如果a是一个类对象,那么a+?就会在a所属的类匹配,匹配?的类型成功后?就会作为唯一参数被代入函数,转换为 operator+(?)进行执行,而a呢?a需要以this的方式或直接使用在函数内进行调用,举个简单的例子
class t_t
{
private:
int a;
public:
t_t(){a=7;}
int operator+(int);
};
int t_t::operator+(int a)
{
return this->a+a;//参数在函数内参数优先级更高,以this的方式调用类中的a
}
int main()
{
t_t a;
cout<<a+2.2<<endl;//隐式转换
cout<<a.operator+(2.2)<<endl;//a+2.2实际转化的函数
return 0;
}
输出为9\n9
单目操作符:操作数只有一个的,比如a ,a++,单目运算符不需要参数(有参数也没用因为无法匹配),举个简单的例子
class t_t
{
private:
int a;
public:
t_t(){a=7;}
int operator!();
};
int t_t::operator!()
{
return a+a;//类中的可以直接调用
}
int main()
{
t_t a;
cout<<!a<<endl;//重载标识符的使用的方法仍和未重载的方法一样
cout<<a.operator!()<<endl;//!a实际转化的函数
return 0;
}
输出结果14\n14
再试试看有一个参数的单目运算符?
class t_t
{
private:
int a;
public:
t_t(){a=7;}
int operator++(int a);
};
int t_t::operator++(int a)
{
return this->a+a;//类中的可以直接调用
}
int main()
{
t_t a;
cout<<a++<<endl;//结果为7
cout<<a.operator++(2)<<endl;//结果为9,说明仅可以通过调用类函数的方法调用
return 0;
}
试试多个参数?
多个参数直接报错,其他情况如下图所示
无参数 | 1个参数 | 多个参数 | |
单目运算符 | 正常执行 | 编译遇到调用语句报错,参数无效,可通过类方法调用执行 | 编译报错 |
双目运算符 | 编译遇到调用语句报错,可通过类方法调用执行 | 正常执行 | 编译报错 |
个人猜测没有固定单目运算符只能对应无参数和双目运算符只能对应一个参数的原因可能是有些运算符既是单目也是双目,比如根据使用的位置,*既可能是乘法符也可能是解引符
非成员运算符重载
由顺序问题引出,在类中的运算符重载只能以一种顺序调用,假设我们定义了类的+int符号,那么只能以a+int 的方式调用
为了使得5+a也能正确调用,那么还可以使用非成员运算符的重载
语法
在括号外的区域声明(文件有效),格式 返回值 operator符号(符号前类型,符号后类型)(双目运算符下) 注意几个点
1.识别匹配仍和符号原用法相同
2.参数里必须有一个类,也就是说无法如下操作
int operator+(int b,int a)//非法,必须有一个类
且非成员运算符要求类类型或枚举类型的参数C/C++(898)
int operator+(t_t a,int b)//合法
int operator+(t_t &a,int b)//合法,参数引用和参数特征标相同
int operator+(t_t *a,int b)//非法,必须是类对象而不是类对象的指针
3.可重载,也会冲突
int t_t::operator+(int a);
int operator+(t_t a,int b);//编译错误,两者特征相同,调用将冲突
友元函数
为了解决非类成员函数无法使用类private内容,在类中声明并且在前面加上friend即可在函数定义中访问类private内容
类的强制类型转换--转换函数
c++的强制类型转换与c语言风格不同
int main()
{
double b=2.2;
cout<<(int)b<<endl;//C style
cout<<int(b)<<endl;//C++
return 0;
}
c++的风格体现了将强制类型转换看作函数,转换函数是用户定义的强制转换类型,可以像使用强制类型转换那样使用他
注意:
1.转换函数必须是类方法
2.不能返回指定类型,返回类型就是此强制转换符号的类型
3.没有参数,参数为该类对象
语法
格式 operator typename()