重载运算
重载运算
算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型.
算数运算符
注意事项:
对于内置的数据类型的表达式的的运算符是不可能改变的
不要滥用运算符重载
成员函数重载:
class Entity { public: int m_X, m_Y; Entity operator+ (Entity& e) { Entity temp; temp.m_X = m_X + e.m_X; temp.m_Y = m_Y + e.m_Y; return temp; } };
调用本质:
e1 = e1.operator+(e2); //== e1 = e1 + e2
全局函数重载:
Entity operator+ (Entity& e1,Entity& e2) { Entity temp; temp.m_X = e1.m_X + e2.m_X; temp.m_Y = e1.m_Y + e2.m_Y; return temp; }
调用本质:
e1 = operator+(e1, e2); //== e1 = e1 + e2
递增和递减运算符
前置递增:
class MyInteger { private: int m_Num1, m_Num2; public: MyInteger& operator++() //必须要返回引用 { m_Num1++; m_Num2++; return *this; } };
后置递增:
MyInteger operator++(int) //不能返回引用,因为返回的是局部变量 { MyInteger ret = *this; m_Num1++; m_Num2++; return ret; }
前置递减:
MyInteger& operator--() { m_Num1--; m_Num2--; return *this; }
后置递减:
MyInteger operator--(int) { MyInteger ret = *this; m_Num1--; m_Num2--; return ret; }
赋值运算符
编译器至少给一个类添加4个函数
- 默认构造函数(无参,函数体为空)。
- 默认析构函数(无参,函数体为空)。
- 默认拷贝构造函数,对属性进行值拷贝。
- 赋值运算符 operator=, 对属性进行值拷贝,为浅拷贝。
因此当有数据开辟到堆区时,需重构赋值运算符进行深拷贝。
class Person { public: int *m_Age; Person(int age) //开辟堆区内存存放数据 { m_Age = new int(age); } Person& operator=(Person &p) //进行深拷贝 { if (m_Age != NULL) //释放原有堆区内存 { delete m_Age; m_Age = NULL; } m_Age = new int(*p.m_Age); //提供深拷贝 解决浅拷贝的问题 return *this; } ~Person() { if (m_Age != NULL) { delete m_Age; m_Age = NULL; } } };
关系运算符
作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
==运算符:
class Person { public: std::string m_Name; int m_Age; bool operator==(Person& p) { if (this->m_Name == p.m_Name && this->m_Age == p.m_Age){ return true; } els{ return false; } } };
!=运算符:
bool operator!=(Person& p) { if (this->m_Name == p.m_Name && this->m_Age == p.m_Age){ return false; } else{ return true; } }
函数调用操作符
由于重载后使用的方式非常像函数的调用,因此称为仿函数.
class MyAdd { public: int operator()(int v1, int v2) { return v1 + v2; } }; int main() { MyAdd add; std::cout << add(10, 10) << std::endl; //匿名对象调用 std::cout << MyAdd()(100, 100) << std::endl; }