C++中的operator主要有两个作用,一是操作符的重载,一是自定义对象类型的隐式转换。
对于操作符的重载,许多人都不陌生,但是对于第二种的自定义对象类型的隐式转换 ,估计不少人都不太熟悉。我们下面就用以下这个小例子展现一下这两种用法:
#include<string>
#include<iostream>
#include<cstdio>
#include<sstream>
using namespace std;
class Test1{
public:
Test1(int value):_value(value){
cout<<"constructor"<<endl;
}
~Test1(){
cout<<"destructor"<<endl;
}
int getValue(){
return _value;
}
void setValue(int value){
_value = value;
}
bool operator() (int x) const{
cout<<"() is overload"<<endl;
return x > _value;
}
operator string(){
cout<<"type convert"<<endl;
stringstream sstr;
sstr<<_value;
return sstr.str();
}
private:
int _value;
};
int main(){
Test1 t(10);
int i = 5;
if(t(5))
cout<<i<<" is greater than "<<t.getValue()<<endl;
else
cout<<i<<" is less than "<<t.getValue()<<endl;
string str(t);
cout<<str<<endl;
return 0;
}
上述的代码输出
constructor
() is overload
5 is less than 10
type convert
10
destructor
bool operator() (int x) 是重载()运算符,使得()成为一个函数对象,即该对象有类似函数的功能,在很多场合下可以当成函数指针使用,在STL的很多算法模板里广泛使用。
operator string()定义Test1对象可以隐身转换成string,这就是operator的第二个用法,注意在函数声明时,operator关键词出现在返回类型的前面,区别与操作符重载时的用法。
Test1类型的对象传入string的构造函数,是用了c++构造函数的隐式类型转换特性,虽然string类并没有显式定义参数为Test1的构造函数,但因为其可以隐式转换为string,所以语法上都是合法的。构造函数的隐式类型转换,是使用一个其他的类型构造当前类的临时对象并用此临时对象来构造当前对象,这种转换必须有构造函数的支持;operator算子的隐式类型转换,使用当前对象去生成另一个类型的对象(正好与构造函数隐式转换相反),这种转换必须有operator算子的支持。当然了,构造函数的隐式类型转换有利有弊,类的设计者就起决定性作用了,如果你不想让构造函数发生隐式的类型转换,请在构造函数前加explicit关键字;同时,operator算子声明的隐式类型转换也可以通过一些相应的返回值函数替代,用户的掌控性更好。