//如果operator+是string类的成员:
string s ="world";
string t = s +"!";//正确,s.operator+("!")。
string u ="hi"+ s;//如果+是string的成员,则产生错误//等价于"hi".operator+(s)//const char*是一种内置类型,没有成员函数//因为string将+定义成了普通的非成员函数,所以"hi"+s等价于operator+("hi",s)
classStrBlobPtr{public://递增和递减运算符
StrBlobPtr&operator++();//前置运算符
StrBlobPtr&operator--();//其他...};
StrBlobPtr& StrBlobPtr::operator++(){//前置版本:返回递增/递减对象的引用//如果curr已经指向了容器的尾后位置,则无法递增它check(curr,"increment past end of StrBlobPtr");++curr;//将curr在当前状态下向前移动一个元素return*this;}
StrBlobPtr& StrBlobPtr::operator--(){//如果curr是0,则继续递减它将参数一个无效下标--curr;//将curr在当前状态下向后移动一个元素check(curr,"decrement past begin of StrBlobPtr");return*this;}
classStrBlobPtr{public://递增和递减运算符
StrBlobPtr operator++(int);//后置运算符
StrBlobPtr operator--(int);//其他成员和之前的版本一致};//后置版本:递增/递减对象的值但是返回原值
StrBlobPtr StrBlobPtr::operator++(int){//此处无须检查有效性,调用前置递增运算符时才需要检查
StrBlobPtr ret =*this;//记录当前的值++*this;//向前移动一个元素,前置++需要检查递增的有效性return ret;//返回之前记录的状态}
StrBlobPtr StrBlobPtr::operator--(int){//此处无须检查有效性,调用前置递减运算时才需要检查
StrBlobPtr ret =*this;//记录当前的值--*this;//向后移动一个元素,前置--需要检查递减的有效性return ret;//返回之前记录的状态}
14.7 成员访问运算符
箭头运算符必须是类的成员。解引用运算符通常也是类的成员,尽管并非必须如此。
classStrBlobPtr{public:
std::string&operator*()const{auto p =check(curr,"deference past end");return(*p)[curr];//(*p)是对象所指的vector}
std::string*operator->()const{//实际工作委托给解引用运算符return&this->operator*();}//...}
plus<int> intAdd;//可执行int加法的函数对象
negate<int> intNegate;//可执行int值取反的函数对象int sum =intAdd(10,20);//使用intAdd::operator()(int,int)求10和20的和
sum =intNegate(intAdd(10,20));//使用intNegate::operator()(int),-30
sum =intAdd(10,intNegate(10));//sum=0;
//定义一个比较简单的类,令其表示0到255之间的一个整数classSmallInt{public:SmallInt(int i =0):val(i){if(i<0|| i>255)throw std::out_of_range("Bad SmallInt value");}operatorint()const{return val;}private:
std::size_t val;};
SmallInt si;
si =4;//首先将4隐式地转换成SmallInt,然后调用SmallInt::operator=
si +3;//首先将si隐式地转换成int,然后执行整数的加法//内置类型转换将double实参转成int
SmallInt si =3.14;//调用SmallInt(int)构造函数//SmallInt的类型转换运算符将si转换成int
si +3.14;//内置类型转换将所得的int继续转换成double
//当istream含有向bool的类中转换时int i =42;
cin << i;//提升后的bool值(1或0)最终被左移42个位置
为了防止转换产生的异常,C++ 11引入了显式的类型转换运算符。
classSmallInt{public://编译器不会自动指向这一类型转换explicitoperatorint()const{return val;}//其他成员与之前的版本一致};
SmallInt si =3;//正确:SmallInt的构造函数不是显式的
si +3;//错误:此处需要隐式的类型转换,但类的运算符是显式的static_cast<int>(si)+3;//正确:显式地请求类型转换
//最好不要在两个类之间构建相同的类型转换structB;structA{A()=default;A(const B&);//把一个B转换成A//其他数据成员};structB{operatorA()const;//也是把一个B转换成A//其他数据成员};
A f(const A&);
B b;
A a =f(b);//二义性错误:含义是f(B::operator A()),还是f(A::A(const B&))?
A a1 =f(b.operatorA());//正确
A a2 =f(A(b));//正确
structA{A(int=0);//最好不要创建两个转换源都是算术类型的类型转换A(double);operatorint()const;//最好不要创建两个转换对象都是算术类型的类型转换operatordouble()const;//其他成员};voidf2(longdouble);
A a;f2(a);//二义性错误:含义是f(A::operator int())还是f(A::operator double())?long lg;
A a2(lg);//二义性错误:含义是A::A(int)还是A::A(double)?short s =42;//把short提升成int优于把short转换成double
A a3(s);//使用A::A(int)