重载的运算符是具有特殊名字的函数。它们的名字由关键字operator和其后要定义的运算符号共同组成。当一个重载的运算符是成员函数时,this绑定到左侧运算对象。成员运算符函数的参数数量比运算对象少一个。
不能被重载的运算符有(::) (.* )(. )(?:)
不应该被重载的运算符: 逻辑运算符,逗号运算符,取地址运算符
选做成员函数的运算符:
=,[ ],( ), ->,
符合赋值+=,-=.. ,
++,–,*(解引用) 改变对象的状态或与给定类型密切相关的运算符
选做非成员函数的运算符:
算数+,-,*,/…
相等性== ,!=
关系 >,<,>=,<=..
位运算符 ^, |, &
重载输入和输出运算符:
必须为非成员函数,输出运算符应该主要负责打印对象的内容而非控制格式,输出运算符不应该打印换行符。输入运算符必须处理输入可能失败的情况,而输出运算符不需要。
#include <string>
class A
{
friend std::ostream& operator<<(std::ostream& os,const A &a);
friend std::istream& operator>>(std::istream& is,A &a);
public:
A(int a=10,std::string s="initial"):value(a),s(s){}
private:
int value;
std::string s;
};
std::ostream& operator<<(std::ostream& os,const A &a)
{
os<<a.value<<a.s;
return os;
}
std::istream& operator>>(std::istream& is,A &a)
{
is>>a.value>>a.s;
if(!is)
{
a=A();
std::cerr<<"invalid input!\n";
}
return is;
}
int main()
{
A a;
std::cin>>a;
std::cout<<a<<std::endl;
return 0;
}
重载相等与不相等运算符:
非成员函数,需具有传递性,定义了其中一个一般需要定义另一个,而通常运算符的一个应该把工作委托给另一个。
#include <iostream>
#include <string>
class A
{
friend bool operator==(const A& a1,const A &a2);
friend bool operator!=(const A& a1,const A &a2);
public:
A(int a=10,std::string s="initial"):value(a),s(s){}
private:
int value;
std::string s;
};
bool operator==(const A& a1,const A &a2)
{
return a1.value==a2.value&&a1.s==a2.s;
}
bool operator!=(const A& a1,const A &a2)
{
return !(a1==a2);
}
int main()
{
A a1,a2(11,"apple"),a3;
std::cout<<(a1==a2)<<std::endl;
std::cout<<(a1==a3)<<std::endl;
std::cout<<(a1!=a2)<<std::endl;
std::cout<<(a1!=a3)<<std::endl;
return 0;
}
重载下标运算符:
成员函数,如果一个类包含下标运算符,则它通常会定义两个版本,一个返回普通引用,另一个类返回常量引用。
#include <iostream>
#include <string>
class A
{
public:
A():value(new int[8]){}
int& operator[](std::size_t n){return value[n];}
const int &operator[](std::size_t n)const {return value[n];}
private:
int *value;
};
int main()
{
A a;
a[5]=8;
std::cout<<a[5]<<std::endl;
const A a1;
//a1[2]=1;//错误
return 0;
}
重载递增和递减运算符:
成员函数,有前置和后置版本,前置返回引用,后置返回值。
#include <iostream>
class A
{
friend std::ostream& operator<<(std::ostream& os,const A &a);
public:
A(int a=0):value(a){};
A & operator++(){
value++;
return *this;
}//前置版本++
A operator++(int){
int tmp=value;
value++;
return *this;
}//后置版本++
A &operator--(){
value--;
return *this;
}//前置版本--
A operator--(int){
int tmp=value;
value--;
return *this;
}//后置版本--
private:
int value;
};
std::ostream& operator<<(std::ostream& os,const A &a)
{
os<<a.value;
return os;
}
int main()
{
A a(8);
++a;
std::cout<<a<<std::endl;//9
--a;
std::cout<<a<<std::endl;//8
a.operator++();
std::cout<<a<<std::endl;//9
a.operator--();
std::cout<<a<<std::endl;//8
return 0;
}
重载成员访问运算符,即*和->
成员函数(不总是),*返回对象的引用,->返回对象的地址。
#include <iostream>
class A
{
public:
A(int a=0):value(a){};
A & operator++(){
value++;
return *this;
}//前置版本++
A operator++(int){
int tmp=value;
value++;
return *this;
}//后置版本++
A &operator--(){
value--;
return *this;
}//前置版本--
A operator--(int){
int tmp=value;
value--;
return *this;
}//后置版本--
int value;
};
class A_ptr
{
public:
A_ptr(A &a):a_ptr(&a){};
A &operator*() const{return *a_ptr;}
A *operator->() const {return a_ptr;}
A *a_ptr;
};
int main()
{
A a(8);
A_ptr ap(a);
std::cout<<ap->value<<std::endl;//8
ap->operator++(); //++a
std::cout<<ap->value<<std::endl;//9
std::cout<<(*ap).value<<std::endl;//9
}