运算符重载
运算符重载的基本概念
运算符重载的需求
- C++预定义的运算符,只能用于基本的数据类型的运算:整形、实型、字符型、逻辑型...
- 在数学上,两个负数可以直接进行+、-等运算。但在C++中,直接将+或-用于复数对象是不允许的
- 有时会希望,让对象也能通过运算符进行运算, 这样代码更简洁,容易理解
- 例如:
- complex_a和complex_b是两个复数对象;
求两个复数的和,希望能直接写 complex_a + complex_b
- complex_a和complex_b是两个复数对象;
运算符重载
- 运算符重载,就是对已有的运算符(C++中预定义的运算符)赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同类型的行为
- 运算符重载的目的是:扩展C++中提供的运算符的适用范围,使之能作用于对象
- 同一个运算符, 对不同的类型的操作数,所发生的行为不同
运算符重载的形式
- 运算符重载的是指是函数重载
- 可以重载为普通函数, 也可以重载为成员函数
- 把含运算符的表达式转换成对运算符函数的调用
- 把运算符的操作数转换成运算符函数的参数
- 运算符被多次重载时, 根据实参的类型决定调用哪个运算符函数
返回值参数 operator 运算符(形参表){
....
}
class Complex {
public:
double real, imag;
Complex(double r = 0, double i = 0): real(r), imag(i){}
Complex operator-(const Complex &c);
};
Complex Complex::operator-(const Complex &c) {
return Complex(real - c.real, imag - c.imag); //返回一个临时对象
}
Complex operator+(const Complex &a, const Complex &b) {
return Complex(a.real + b.real, a.imag + b.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;
}
赋值运算符的重载
有时候希望赋值运算符两边的类型可以不匹配,比如, 把一个int类型变量赋值给一个Complex对象,或把一个char*类型的字符串赋值给一个字符串对象,此时就需要重载运算符“=”
赋值运算符“=”只能重载为成员函数
class String {
private:
char *str;
public:
String():str(new char[1]){str[0] = 0;}
const char *get_str(){return str;};
String &operator = (const char *s);
~String(){delete []str;}
};
String &String::operator=(const char *s) {
delete []str;
str = new char[strlen(s) + 1];
strcpy(str, s);
return *this;
}
int main() {
String s;
s = "Hello";
cout << s.get_str() << endl;
// String s2 = "world"; //这句话要是不注释掉会报错,初始化句会调用构造函数而不是赋值重载
s = "world";
cout << s.get_str() << endl;
return 0;
}