C++运算符重载
什么是运算符重载
运算符重载就是运算符重新赋予运算能够操作自定义类型
注意:运算符重载的前提条件是必定存在一个自定义类型
运算符重载的实质就是函数的调用
两种方式
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;
}