运算符重载
加号运算符重载
作用:实现两个自定义数据类型相加的运算。
#include <iostream>using namespace std;class Person
{
public:Person() {}Person(int a, int b){this->a = a;this->b = b;}Person operator+(const Person &p){Person temp;temp.a = this->a + p.a;temp.b = this->b + p.b;return temp;}public:int a;int b;
};Person operator+(const Person &p, int val)
{Person temp;temp.a = p.a + val;temp.b = p.b + val;return temp;
}void test()
{Person p1(10, 20);Person p2(20, 20);Person p3 = p1 + p2;cout << "p3.a = " << p3.a << "p3.b = " << p3.b << endl;Person p4 = p3 + 10;cout << "p4.a = " << p4.a << "p4.b = " << p4.b << endl;
}int main()
{test();return 0;
}
总结1:对于内置的数据类型的表达式的的运算符是不可能改变的
总结2:不要滥用运算符重载
左移运算符重载
作用:可以输出自定义数据类型
#include <iostream>
using namespace std;
class Person
{friend ostream &operator<<(ostream &out, Person &p);public:Person(int a, int b){this->m_A = a;this->m_B = b;}// 成员函数 实现不了 p << cout 不是我们想要的效果// void operator<<(Person& p){// }private:int m_A;int m_B;
};// 全局函数实现左移重载
// ostream对象只能有一个
ostream &operator<<(ostream &out, Person &p)
{out << "a:" << p.m_A << " b:" << p.m_B;return out;
}void test()
{Person p1(10, 20);cout << p1 << "hello world" << endl; // 链式编程
}int main()
{test();return 0;
}
总结:重载左移运算符配合友元可以实现输出自定义数据类型
递增运算符重载
作用: 通过重载递增运算符,实现自己的整型数据
class MyInteger {friend ostream& operator<<(ostream& out, MyInteger myint);public:MyInteger() {m_Num = 0;}//前置++MyInteger& operator++() {//先++m_Num++;//再返回return *this;}//后置++MyInteger operator++(int) {//先返回MyInteger temp = *this; //记录当前本身的值,然后让本身的值加1,但是返回的是以前的值,达到先返回后++;m_Num++;return temp;}private:int m_Num;
};ostream& operator<<(ostream& out, MyInteger myint) {out << myint.m_Num;return out;
}//前置++ 先++ 再返回
void test01() {MyInteger myInt;cout << ++myInt << endl;cout << myInt << endl;
}//后置++ 先返回 再++
void test02() {MyInteger myInt;cout << myInt++ << endl;cout << myInt << endl;
}int main() {test01();//test02();system("pause");return 0;
}
总结: 前置递增返回引用,后置递增返回值
赋值运算符重载
c++编译器至少给一个类添加4个函数
-
默认构造函数(无参,函数体为空)
-
默认析构函数(无参,函数体为空)
-
默认拷贝构造函数,对属性进行值拷贝
-
赋值运算符 operator=, 对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
class Person
{
public:Person(int age){//将年龄数据开辟到堆区m_Age = new int(age);}//重载赋值运算符 Person& operator=(Person &p){if (m_Age != NULL){delete m_Age;m_Age = NULL;}//编译器提供的代码是浅拷贝//m_Age = p.m_Age;//提供深拷贝 解决浅拷贝的问题m_Age = new int(*p.m_Age);//返回自身return *this;}~Person(){if (m_Age != NULL){delete m_Age;m_Age = NULL;}}//年龄的指针int *m_Age;};void test01()
{Person p1(18);Person p2(20);Person p3(30);p3 = p2 = p1; //赋值操作cout << "p1的年龄为:" << *p1.m_Age << endl;cout << "p2的年龄为:" << *p2.m_Age << endl;cout << "p3的年龄为:" << *p3.m_Age << endl;
}int main() {test01();//int a = 10;//int b = 20;//int c = 30;//c = b = a;//cout << "a = " << a << endl;//cout << "b = " << b << endl;//cout << "c = " << c << endl;system("pause");return 0;
}
函数调用运算符重载
-
函数调用运算符 () 也可以重载
-
由于重载后使用的方式非常像函数的调用,因此称为仿函数
-
仿函数没有固定写法,非常灵活
#include <iostream>
using namespace std;
class MyPrinft
{
public:void operator()(string text){cout << text << endl;}
};void test1()
{// 重载的()操作符,也成为仿函数MyPrinft myFunc;myFunc("Hello World !");
}
class MyAdd
{
public:int operator()(int v1, int v2){return v1 + v2;}
};
void test2()
{MyAdd add;int ret = add(10, 10);cout << "ret = " << ret << endl;// 匿名对象调用cout << "MyAdd()(100,100) = " << MyAdd()(100, 100) << endl;
}int main()
{test1();test2();return 0;
}