一、为啥要搞运算符重载
我们平时用的C++也好,还是其他语言预定义好的运算符,一般都是限定于基本数据类型,如整型变量的加法int c = a+b等,但是操作的数据类型是我们自定义的时候(如类)就不能用预定义运算符,这时就需要用到运算符重载了。
回顾C++的动态联编和静态联编:
(1)静态联编支持的多态性称为编译时多态性,也称静态多态性。
编译时多态性是通过函数重载(包括运算符重载)和模板实现的。
(2)动态联编所支持的多态性称为运行时多态性,也称动态多态性。
在C++中,运行时多态性是通过虚函数来实现的。
二、一个栗子
下面看一个运算符重载的栗子,我们让两个立方体“相加”,但是这个“相加”我们用了运算符重载,定义的相加得到长、宽、高分别求和后的新立方体。
#include <iostream> using namespace std; class Box{ public: double getVolume(void){ return length * breadth * height; } void setLength( double len ){ length = len; } void setBreadth( double bre ){ breadth = bre; } void setHeight( double hei ){ height = hei; } // 重载 + 运算符,用于把两个 Box 对象相加 Box operator+(const Box& b){ Box box; box.length = this->length + b.length; box.breadth = this->breadth + b.breadth; box.height = this->height + b.height; return box; } private: double length; // 长度 double breadth; // 宽度 double height; // 高度 }; // 程序的主函数 int main( ){ Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box Box Box3; // 声明 Box3,类型为 Box double volume = 0.0; // 把体积存储在该变量中 // Box1 详述 Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); // Box2 详述 Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // Box1 的体积 volume = Box1.getVolume(); cout << "Volume of Box1 : " << volume <<endl; // Box2 的体积 volume = Box2.getVolume(); cout << "Volume of Box2 : " << volume <<endl; // 把两个对象相加,得到 Box3 Box3 = Box1 + Box2; // Box3 的体积 volume = Box3.getVolume(); cout << "Volume of Box3 : " << volume <<endl; return 0; }
Volume of Box1 : 210 Volume of Box2 : 1560
三、运算符重载注意事项
一个重载的运算符必须是某个类的成员或者至少拥有一个类类型的运算对象。
重载运算符的运算对象数量、结合律、优先级与对应的用于内置类型的运算符相同。
当运算符被定义为类的成员时,类对象的隐式this指针绑定到第一个运算对象。赋值、下标、函数调用和箭头运算符必须作为类的成员。
如果类重载了函数调用运算符operator(),则该类的对象,称为【函数对象】。lambda表达式能简便定义函数对象类。
可以重定义或重载大部分 C++ 内置的运算符,函数名是由关键字 operator
和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);
声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数:
Box operator+(const Box&, const Box&);