1.基础知识
1.1 运算符重载的目的
如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。未经重载的运算符不能用于对象之间的运算。
运算符重载 是为了进行对象之间的运算,并且是同类型对象之间的运算。
运算符重载的实质是 编写以[operator 运算符]作为名称的函数。该函数可以作为类的成员函数,也可以作为普通的类外的函数。
1.2运算符重载的格式
不妨把这样的函数称为运算符函数。运算符函数的格式如下:
返回值类型 operator 运算符(形参表)
{
....
}
把 operator 运算符 (比如 operator +)这两个连起来的东西看做一个整体
1.3运算符重载后的调用
包含被重载的运算符的表达式 会被编译 成对运算符函数的调用,运算符的操作数成为函数调用时的实参,运算的结果就是函数的返回值。运算符可以被多次重载。
简而言之:重载后的运算符 在调用处的代码,编译时,被替换
有了对+
的重载,编译器就将c=a+b
理解为对运算符函数的调用,即c=operator+(a,b)
2. "+" ,"- "加号,减号 ,运算符的重载
注意:内的内部的运算符重载函数和类外部的不一样
重点:运算符重载为全局函数时,参数的个数等于运算符的目数(即操作数的个数);运算符重载为成员函数时,参数的个数等于运算符的目数减一。
#include <iostream>
using namespace std;
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)
{ //下面语句为第12行
return Complex(a.real + b.real, a.imag + b.imag); //第12行返回一个临时对象
}
//类内部的 运算符重载函数 传入参数比目数 少1 (需要调用自身的类的成员变量)
Complex Complex::operator - (const Complex & c)
{
return Complex(real - c.real, imag - c.imag); //第16行返回一个临时对象
}
int main()
{
Complex obj_a(10, 20), obj_b(5, 1), obj_c;
obj_c = obj_a + obj_b; //等价于 obj_c = operator + (obj_a,obj_b);
cout << obj_c.real << "," << obj_c.imag << endl;//15,21
obj_c=obj_a-obj_b;//obj_a-obj_b等价于obj_a.operator - (b)
cout << c.real << "," << obj_c.imag << endl;//5,19
cout << (obj_a - obj_b).real << "," << (obj_a - obj_b).imag << endl;
//5,19 obj_a-obj_b等价于obj_a.operator - (obj_b)
return 0;
}
类内部定义的运算符重载函数 具体执行时的细节
c=a-b;//a-b等价于a.operator - (b) operator - (b)就是运算符重载函数,此时,传入参数是b,即双目运算时,后面一个参数是传入参数
有了对+
的重载,编译器就将c=a+b
理解为对运算符函数的调用,即c=operator+(a,b);
第 12 行,在 C++ 中,“类名(构造函数实参表)”这种写法表示生成一个临时对象。该临时对象没有名字,生存期就到包含它的语句执行完为止。因此,第 12 行实际上生成了一个临时的 Complex 对象作为 return 语句的返回值,该临时对象被初始化为 a、b 之和。第 16 行与第 12 行类似。
3. " = "等号运算符的重载
"=" 运算符重载的 只能是类的成员函数
"=" 运算符重载的特殊性
赋值运算符“=”
要求左右两个操作数的类型是匹配的,或至少是兼容的,这是赋值运算符的现状。
赋值运算符“=”
重载的目的
有时希望=
两边的操作数的类型即使不兼容也能够成立,这就需要对=
进行重载。C++规定,=
只能重载为成员函数。
4."()"运算符重载
"()" 运算符重载的 只能是类的成员函数
#include <iostream>
class MyFunction {
private:
int value;
public:
MyFunction(int val=0) : value(0) {}
void operator()(int val) {
value = value + val;
std::cout << "New value: " << value << std::endl;
}
};
int main() {
MyFunction func(5);//执行构造函数
func(3); //执行运算符重载函数 调用函数对象,将参数值传递给括号运算符
return 0;
}
class cls
{
public:
void operator() () //重载"()"操作符,"()"内无操作数
{
printf("HelloWorld!\n");
}
void operator() (const char* str) //重载"()","()"内的操作数是字符串
{
printf("%s", str);
}
};
int main(void)
{
cls cc;
cc();//执行无参的括号运算符重载函数
cc("Hello Linux\n");//执行有参的括号运算符重载函数
return 0;
}
注意:区分对象的构造函数和括号运算符重载函数。构造函数只在定义对象时执行。
单一的对象加括号的形式,如 对象() 的结合体,一定是该对象里面的括号运算符重载函数。