重载
对已有的运算符赋予多重含义,使得同一运算符作用于不同数据类型的数据时导致不同类型的行为。 形式: 返回值类型 operator 运算符(形参表){} 注意,当重载为成员函数时,参数个数为运算符数目-1. 例子:
class Complex{
public:
double real,imag;
Complex(double r = 0.0,double i = 0.0):real(r),imag(i){}
Complex operator-(const Complex &c);
};
Complex operator+(const Complex &a,const Complex &b)
{
return Complex(a.real+b.real,a.imag+b.imag);
}
Complex Complex::operator+(const Complex &c)
{
return Complex(real-c.real,imag-c.imag);
}
调用时:
- 赋值运算符重载
它只能重载为成员函数 简单用法如下: 问题:
String s1,s2;
s1="this";s2="that";
s1=s2;
使用原生的赋值运算符,可以吗?答案是no。 看一下会出现的问题:
- this的空间失去了指针指向它,没有被delete就废弃了,产生内存垃圾。
- 如果s1消亡,析构函数会delete s1所指向的内存空间。s2也就无所指了。当s2消亡,再一次析构delete已经删除的空间,程序崩溃。
这里如果再令S2=“other”;S1指向仍是that。因为S2=“other”,是将S2指向other所在的内存地址,而不是修改S2已经指向的地址单元的值。 解决方法:
- 流插入和流提取运算符重载
cout是ostream类的对象,cin是istream类的对象。这两个类均定义在iostream中。 在类中分别对<<和>>进行了重载。 针对输出/输入的不同类型,c++重载了多个成员函数。 比如输出int:
void ostream::operator<<(int n){
......
return;
}
当我们想要输出特定的格式的数据时,比如复数,简单的调用cout<<输出对象肯定就不行了。自己根据需要重载<<流插入和>>流提取运算符。下面以输入输出复数类举例。
int main(){
Complex c;
int n;
cin>>c>>n;
cout<<c<<",";
return 0;
}
class Complex{
double real,imag;
public:
Complex(double r = 0,double i = 0):real(r),imag(i){};
friend ostream& operator<<(ostream& os,const Complex& c);
friend istream& opeator>>(istream& is,Complex& c);
}
ostream& operator<<(ostream& os,const Complex& c){
os<<c.real<<"+"<<c.imag<<"i";
return os;
}
流提取运算符的重载类似,做一些字符串分割处理即可。注意接收键盘输入,不能为const。
class CDemo{
private: int n;
public:
CDemo(int i = 0):n(i){}
CDemo& operator++();
CDemo operator++(int);
operator int(){return n;}
friend CDemo& operator--(CDemo&);
friend CDemo& operator--(CDemo&,int);
};
CDemo& CDemo::operator++()
{
++n;
return *this
}
CDemo CDemo::operator++(int){
CDemo temp(*this);
n++;
return temp;
}
CDemo operator--(CDemo& d){
d.n--;
return d;
}
CDemo operator--(CDemo& d,int){
CDemo temp(d);
d.n--;
return temp;
}
最后再补充一点重载的注意事项
|