运算符重载
运算符重载就是对已有的运算符(c++中预定义的运算符)赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同类型的行为。
运算符重载的实质就是函数重载。
可以重载为普通函数,也可以重载为成员函数。
把含运算符的表达式转换为对运算符函数的调用。
把运算符的操作数转换成运算符函数的参数。
运算符被多次重载时,根据实参的类型决定调用哪个运算符函数。
运算符重载的形式
/*
返回值类型 operator运算符(形参表)
{
....
}
*/
//运算符重载实例
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
*/
赋值运算符重载
有时候希望赋值运算符两边的类型可以不匹配,此时需要重载赋值运算符“=”。
赋值运算符“=”只能重载为成员函数。
class String
{
private:
char *str;
public:
String():str(new char[1]) //new char[1]返回char *
{
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"能够成立
{
delete []str;
str = new char[strlen(s) + 1];
strcpy(str, s);
return *this;
}
int main()
{
String s;
s = "Good Luck,"; //等价于s.operator=("Good Luck,");
cout << s.c_str() << endl;
//String s2 = "hello!"; //这条语句要是不注释掉就会出错,这是一条初始化语句,不是赋值语句
s = "Shenzhou 8!"; //等价于s.operator=("Shenzhou 8!");
cout << s.c_str() << endl;
return 0;
}
/*
输出:
Good Luck,
Shenzhou 8!
*/
运算符重载为友元函数
//一般情况下,将运算符重载为类的成员函数,是较好的选择。
//但是,有时重载为成员函数不能满足需求,重载为普通函数又不能访问类的私有成员,所以需要将运算符重载为友元。
class Complex
{
double real, imag;
public:
Complex(double r, double i):real(r), imag(i) {}
Complex operator+(double r);
};
Complex Complex::operator+(double r)
{
return Complex(real + r, imag); //能解释c+5
}
int main()
{
Complex c(0, 0);
c = c + 5; //有定义,相当于 c = c.operator+(5);
c = 5 + c; //(1)编译出错
/*
为了使(1)成立,需要将+重载为普通函数。
Complex operator+(double r, const Complex &c)
{
return Complex(c.real + r, c.imag); //能解释5 + c;
}
但是上面的函数为普通函数,不能访问类的私有成员,所以需要将运算符+重载为友元。
即在Complex类中加入下面语句:
friend Complex operator+(double r, const Complex &c);
*/
return 0;
}
//完整程序
class Complex
{
friend void Print(Complex c);
friend Complex operator+(double r, Complex &c);
private:
double real, imag;
public:
Complex(double r, double i):real(r), imag(i){}
Complex operator+(double r);
};
Complex Complex::operator+(double r)
{
return Complex(real + r, imag);
}
Complex operator+(double r, Complex &c)
{
return Complex(c.real + r, c.imag);
}
void Print(Complex c)
{
cout << c.real << "," << c.imag << endl;
}
int main()
{
Complex c(0, 0);
c = c + 5; //有定义,相当于 c = c.operator+(5);
Print(c);
c = 5 + c;
Print(c);
return 0;
}