什么是运算符重载
运算符重载就是运算符重新赋予运算能够操作自定义类型
注意:运算符重载的前提条件是必定存在一个自定义类型
运算符重载的实质就是函数的调用
两种方式
1.友元重载
2.类重载
重载的写法
运算符重载也是一个函数,只是函数名的写法不同,其余的跟函数的写法类似
函数的写法:
函数返回值类型 函数名(参数)
{
函数体
}
**> 运算符重载函数的写法:
函数名:operate加上运算符,就组成了函数名
参数:
类成员函数:参数个数 = 操作个数 - 1
友元函数:参数个数 = 操作个数
**
运算符重载的注意事项
注意:
1.在同一个自定义类型中,一个运算符只能被重载一次
2.C++重载只能重载已有的运算符,不能自己创造运算符
3.C++重载一般不能违背运算符原来有的含义,就算语法正确也不能够去违背
为什么要使用运算符重载
如图报错信息,编译器对于自定义类型的运算并不支持,这就需要我们进行运算符重载。
友元函数运算符重载
#include<iostream> #include<string> using namespace std; class MM { public: MM(int age, string name):age(age), name(name){} friend MM operator + (MM & object1, MM & object2); //友元函数运算符重载 void print() { cout << name << age << endl; } private: int age; string name; }; MM operator + (MM & object1, MM & object2) { return MM(object1.age + object2.age, object1.name); //注意:这里返回一个匿名对象 } int main() { MM mm1(10, "温柔了岁月"); MM mm2(11, "温柔了岁月"); MM mm3 = mm1 + mm2; //在vs中绿色的就是运算符重载 这是函数的隐式调用 MM mm4 = operator + (mm1, mm2); //函数的显示调用 mm3.print(); system("pause"); return 0; }
类成员函数运算符重载
#include<iostream> #include<string> using namespace std; class MM { public: MM(int age, string name):age(age), name(name){} MM operator + (MM& object) //有一个是对象本身,所以比操作的数据成员少一个 { return MM(this->age + object.age, this->name); } void print() { cout << age << name << endl; } private: int age; string name; }; int main() { MM mm1(10, "温柔了岁月"); MM mm2(12, "温柔了岁月"); MM mm3 = mm1 + mm2; //隐式调用 mm3.print(); MM mm4 = mm1.operator + (mm2); //显示调用 mm4.print(); system("pause"); return 0; }
特殊运算符重载
1.通常情况下,单目运算符用类成员函数重载,双目用友元重载
2. = ,(),->,[], 只能采用成员函数重载
=运算符重载
1.每个类都存在一个赋值运算符重载
2.你可以用delete删除默认的赋值运算符重载
3.你也可以在写一个赋值运算符重载,你也可以根据需要,自己在写一个赋值运算符重载只不过作用跟默认的不太一样
#include<iostream> #include<string> using namespace std; class MM { public: MM(int age, string name):age(age), name(name){} private: int age; string name; }; int main() { MM mm1 = MM(10, "温柔了岁月"); //显式 MM mm2(10, "温柔了岁月"); //隐式 MM girl = mm1; //每个类中都存在一个默认的赋值运算符重载 system("pause"); return 0; }
++ ,–运算符重载
这比较特殊,++,–重载差不多,
主要学会区分前自增和后自增,前自减和后自减的重载函数的区别
方法:增加一个无用的参数,来区分
include<string> #include <iostream> using namespace std; class MM { public: MM(int age, string name) : age(age), name(name) {} MM operator ++ () //前自增 { this->age++; return *this; } MM operator ++ (int) //后自增 效率比第一种低,因为要创造对象,需要花时间 { return MM(this->age++, this->name); } void print() { cout << name << " " << age << endl; } private: int age; string name; }; int main() { MM mm(10, "温柔了岁月"); mm++; mm.print(); MM mm2 = MM(10, "温柔了岁月"); ++mm2; mm2.print(); system("pause"); return 0; }
流运算符重载
输出流 << ,类型ostream
输入流 >> , 类型 istream
注意事项:
1.流重载必须要用引用的方式
2.流重载必须用友元函数重载(因为会修改一些私有的属性)
#include<iostream> #include<string> using namespace std; class MM { public: MM() {}; MM(int age, string name) : age(age), name(name) {} friend ostream& operator << (ostream& out, MM& object1); friend istream& operator >> (istream& in, MM& object2); private: int age; string name; }; ostream& operator << (ostream& out, MM& object1) //输出流 { out << object1.age << object1.name << endl; return out; } istream& operator >> (istream& in, MM& object2) //输入流 { cout << "请输入年龄和名字" << endl; in >> object2.age >> object2.name; return in; } int main() { MM girl; cin >> girl; cout << girl << endl; system("pause"); return 0; }
()运算符重载
它实际上是一个仿函数
就是让类模仿函数调用的行为
后期在STL中,用于自己写自定义类型的比较
#include<iostream> #include<string> using namespace std; class MM { public: MM(){}; MM(int age, string name) : age(age) , name(name) {} void operator ()() { cout << "无参" << endl; } void operator () (int a, int b) { cout << "有参" << endl; } private: int age; string name; }; int main() { MM mm1(); MM(); MM{}(1, 2); // {}帮助识别,因为编译器不知道是调用函数,还是构造函数。 MM mm2; mm2.operator()(); mm2.operator()(1, 2); //显式调用 MM mm3; mm3(); //隐式调用 mm3(1, 3); system("pause"); return 0; }