允许重载的运算符
不要重载&&、||。因为用户无法实现&&和||的短路特性。
不允许重载的运算符
规则
不可以自己定义新的运算符,只能对已有的C++运算符重载。
不能改变运算符运算对象的个数。
函数中的参数个数取决于两个因素:
1.运算符是一元(一个参数)还是二元(两个参数)
2.运算符被定义为全局函数(一元--一个参数,二元--两个参数)还是成员函数(一元--没有参数,二元--一个参数)
不能改变运算符的优先级和结合性
应与标准类型运算功能相似,避免影响可读性。
一般格式
和函数定义的一般方法一样,只是函数名变成了:operator运算符
方法
方法1:成员函数完成运算符重载
方法2:全局函数作为友元完成重载
区分
如果运算符的参数含有非成员数据(如cout),则使用友元的方法
如果操作数都是成员数据,则可以使用成员函数的方法,并且可以省略一个参数(this指向第一个参数)
分类
根据运算符操作数的不同:双目运算符作为类成员函数,单目运算符作为类的成员函数,双目运算符作为类的友员函数,单目运算符作为类的友元函数。
双目运算符作为友元函数时需要制定两个参数。
运算符重载函数作为类成员函数可以显式调用。
常用运算符的重载
自增自减
前置++a,--a
后置a++,a--
int形参并不会被使用,所以无需命名
赋值运算符
注意:重载的返回值是(*this)
例:
#include <iostream> class MyClass { private: int data; public: // 构造函数 MyClass(int value = 0) : data(value) {} // 重载赋值运算符 MyClass& operator=(const MyClass& other) { if (this != &other) { data = other.data; } return *this; } };
返回return *this的原因:防止对象被复制或移动,并且还可以支持连续操作。
如果不返回引用类型,会导致赋值操作不修改原始对象,而是在新对象上进行修改。会引发内存泄漏,因为对象的 data 指针会在每次赋值操作后分配新内存而没有释放旧内存。
输入/输出运算符
特殊:实现类型转换
不指定函数类型和参数,返回值的类型由类型名来确定。
类型转换函数只能作为成员函数,不能作为友元函数。
类型转换函数的一般形式:
class Vector3 { public: Vector3(); Vector3(double x,double y,double z); public: Vector3 operator+(const Vector3 &A)const; Vector3 operator++(); friend Vector3 operator-(const Vector3 &v1, const Vector3 &v2); friend Vector3 operator--(Vector3 &v,int); operator double() { return m_x + m_y + m_z; } void display()const; private: double m_x; double m_y; double m_z; }; int main() { Vector3 v1(1, 2, 3); double d = v1; cout << d << endl;//6 return 0; }
重载运算符函数为什么需要引用类型
返回引用==返回他本身
1.实现链式操作
2.避免拷贝
如果返回的是对象副本而不是引用,会涉及到额外的拷贝构造函数调用和内存操作,造成不必要的开销。