目录
运算符重载
定义
运算符重载,就是对已有的运算符(C++中预定义的运算符)赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同类型的行为。
对运算符进行重载的时候,好的风格是应该尽量保留运算符原本的类型。
目的
扩展C++中提供的运算符的适用范围,使之能作用于对象。
实质
函数重载。可以重载为普通函数,也可以重载为成员函数。
形式
返回值类型 operator 运算符(形参表)
{
……
}
加减运算符重载示例
Complex_a和Complex_b是两个复数对象;求两个复数的和, 希望能直接写: Complex_a + Complex_b。
//复数加减法
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);
}
int main()
{
Complex a(4,4),b(1,1),c;
c = a + b; //等价于c=operator+(a,b);
cout << c.real << "," << c.imag << endl;
cout << (a-b).real << "," << (a-b).imag << endl;
//a-b等价于a.operator-(b)
return 0;
}
————————————————————————————————————————————————————————————————
输出:
5,5
3,3
赋值运算符重载示例
把一个 char * 类型的字符串赋值给一个字符串对象,此时就需要重载赋值运算符“=”。
注:赋值运算符“=”只能重载为成员函数。
class String {
private:
char *str;
public:
String():str(new char[1]) {str[0] = 0;}
const char * c_str() {return str; };
String & operator = (const char *s);
~String() {delete [] str; }
};
String & String::operator = (const char *s)
{ //重载“=”以使得 obj = “hello”能够成立
if(this == &s)//防止s = s该情况无效内存访问
return * this;
delete [] str;
str = new char[strlen(s)+1];
strcpy( str, s);
return * this;
}
流插入运算符重载示例
cout 是在 iostream 中定义的,ostream 类的对象,“<<” 能用在cout 上是因为,在iostream 里对 “<<” 进行了重载。
ostream & ostream::operator<<(int n)
{
…… //输出n的代码
return * this;
}
ostream & ostream::operator<<(const char * s )
{
…… //输出s的代码
return * this;
}
类型转换运算符重载示例
类型转换运算符在重载时不需要注明返回值类型,不需要在前面写double。
#include <iostream>
using namespace std;
class Complex
{
double real,imag;
public:
Complex(double r=0,double i=0):real(r),imag(i) { };
operator double () { return real; }//重载强制类型转换运算符 double
};
int main()
{
Complex c(1.2,3.4);
cout << (double)c << endl; //输出 1.2
double n = 2 + c; //等价于 double n=2+c.operator double()
cout << n; //输出 3.2
}
自增自减运算符重载示例
自增运算符++、自减运算符--有前置/后置之分。
- 前置运算符作为一元运算符重载,返回值是对象的引用。
- 后置运算符作为二元运算符重载,多写一个没用的参数,返回值是临时的对象。
注:尽量使用++i,其性能高于i++,作用对象时较明显。
class CDemo {
private:
int n;
public:
CDemo(int i=0):n(i) { }
CDemo & operator++(); //前置成员函数
CDemo operator++(int k); //后置成员函数
operator int () { return n; }//类型转换成员函数
friend CDemo & operator--(CDemo & d);//前置友元普通函数,可在外部访问私有变量
friend CDemo operator--(CDemo & d,int k);//后置友元普通函数
};
//重载为成员函数
CDemo & CDemo::operator++()
{ //前置 ++
n ++;
return * this;
} // ++s即为: s.operator++();
CDemo CDemo::operator++(int k)
{ //后置 ++
CDemo tmp(*this); //记录修改前的对象
n ++;
return tmp; //返回修改前的对象
} // s++即为: s.operator++(0);
//重载为普通函数
CDemo & operator--(CDemo & d)
{//前置--
d.n--;
return d;
} //--s即为: operator--(s);
CDemo operator--(CDemo & d,int k)
{//后置--
CDemo tmp(d);
d.n --;
return tmp;
} //s--即为: operator--(s, 0);