五、运算符重载
![]()
1、加号运算符重载
![]()
![]()
#include <iostream>
#include <string>
using namespace std;
//加号运算符重载
class Person {
public:
//1.成员函数重载+号
Person operator+(Person &p) {
Person temp;
temp.m_A = this->m_A + p.m_A;
temp.m_B = this->m_B + p.m_B;
return temp;
}
int m_A;
int m_B;
};
//2.全局函数重载+号
//Person operator+(Person &p1, Person &p2) {
// Person temp;
// temp.m_A = p1.m_A + p2.m_A;
// temp.m_B = p1.m_B + p2.m_B;
// return temp;
//}
//运算符重载也可以发生函数重载
Person operator+(Person &p1, int num) {
Person temp;
temp.m_A = p1.m_A + num;
temp.m_B = p1.m_B + num;
return temp;
}
void test01() {
Person p1;
p1.m_A = 10;
p1.m_B = 10;
Person p2;
p2.m_A = 10;
p2.m_B = 10;
//成员函数重载本质调用
//Person p3 = p1.operator+(p2);
//全局函数重载本质调用
//Person p3 = operator+(p1, p2);
//简写成
Person p3 = p1 + p2;
//运算符重载也可以发生函数重载
Person p4 = p1 + 100;
cout << "p3.m_A = " << p3.m_A << endl;
cout << "p3.m_B = " << p3.m_B << endl;
cout << "p4.m_A = " << p4.m_A << endl;
cout << "p4.m_B = " << p4.m_B << endl;
}
int main() {
test01();
system("pause");
return 0;
}
![]()
2、左移运算符重载
![]()
![]()
#include <iostream>
#include <string>
using namespace std;
//左移运算符重载
class Person {
//重载左移运算符配合友元可以实现输出自定义数据类型
friend ostream & operator<<(ostream &out, Person &p);
public:
Person(int a, int b) :m_A(a),m_B(b){
}
//1.利用成员函数重载左移运算符
//不会利用成员函数重载<<运算符,因为无法实现cout在左侧
/*
void operator<<(Person &p) ==> p.operator<<(p) 不合适
void operator<<(cout) ==> p.operator<<(cout)
简化版本 p << cout ,cout不在左侧,不合适
*/
private:
int m_A;
int m_B;
};
//2.利用 全局函数实现左移运算符
/*本质 operator<<(cout,&p) 简化 cout << p
ostream 输出流对象只能有一个,用引用的方式参数传递
返回ostream 链式编程思想可以用于追加输出别的内容
*/
ostream & operator<<(ostream &out,Person &p) {
//友元支持访问类中私有成员变量
out << "m_A = " << p.m_A << " m_B = " << p.m_B;
return out;
}
void test01() {
//构造函数赋初值
Person p(10,10);
//链式编程
//<< 返回ostream的对象 可以后面输出<< " Hello world" << endl;
cout << p << " Hello world" << endl;
}
int main() {
test01();
system("pause");
return 0;
}
3、递增运算符重载
![]()
![]()
#include <iostream>
#include <string>
using namespace std;
//重载递增运算符
//自定义整形
class MyInterger {
friend ostream& operator<<(ostream& cout, MyInterger myint);
public:
MyInterger():m_Num(0){}
//重载前置++运算符
//为什么返回引用,不返回值
/*
和真实前置++一致
++(++a) 2
a 2
而返回值:
++(++myint) 2
myint 1
前后两次不是一个对象,第一次加后对新的对象做了递增
*/
MyInterger& operator++() {
m_Num++; //先++
return *this; //再将自身做返回
}
//重载后置++运算符
/*
void operator++(int)
其中int代表占位参数
可以用于区分前置和后置(只认int)
为什么返回值,不返回引用
返回局部对象,当前函数执行完后释放,对象被释放
返回引用,后续是非法操作
*/
MyInterger operator++(int) {
MyInterger temp = *this; //先记录当时的结果
m_Num++; //后递增
return temp; //最后将记录结果返回
}
private:
int m_Num;
};
//全局函数 << 运算符重载
ostream& operator<<(ostream& cout, MyInterger myint) {
cout << myint.m_Num;
return cout;
}
void test01() {
MyInterger myint;
cout << ++(++myint) << endl; //2
cout << myint << endl; //2
}
void test02() {
MyInterger myint;
cout << myint++ << endl; //0
cout << myint << endl; //1
}
int main() {
test01();
//test02();
system("pause");
return 0;
}
#include <iostream>
#include <string>
using namespace std;
//重载递减运算符
class MyInterger {
friend ostream& operator<<(ostream & cout, MyInterger mint);
public:
MyInterger() :m_Num(10) {}
//前置--
MyInterger& operator--() {
--m_Num;
return *this;
}
//后置--
MyInterger operator--(int) {
MyInterger temp = *this;
m_Num--;
return temp;
}
private:
int m_Num;
};
ostream& operator<<(ostream & cout, MyInterger mint) {
cout << mint.m_Num;
return cout;
}
void test01() {
MyInterger myint;
cout << --(--myint) << endl; //8
cout << myint << endl; //8
}
void test02() {
MyInterger myint;
cout << myint-- << endl; //10
cout << myint << endl; //9
}
int main() {
test01();
test02();
system("pause");
return 0;
}
4、赋值运算符重载
![]()
![]()
![]()
#include <iostream>
#include <string>
using namespace std;
//赋值运算符重载
class Person {
public:
Person(int age) {
m_Age = new int(age); //堆区
}
~Person() {
if (m_Age != NULL) {
delete m_Age; //手动释放
m_Age = NULL;
}
}
//重载赋值运算符
Person& operator=(Person &p) {
//编译器提供的时浅拷贝
//m_Age = p.m_Age;
//应该先判断是否有属性在堆区,如果有,先释放干净,然后再深拷贝
if (m_Age != NULL) {
delete m_Age;
m_Age = NULL;
}
//深拷贝
m_Age = new int(*p.m_Age);
return *this;
}
int * m_Age;
};
void test01() {
Person p1(18);
Person p2(20);
Person p3(30);
p1 = p2 = p3; //赋值操作,默认浅拷贝,在析构函数释放时暴露问题
cout << "p1的年龄: " << *p1.m_Age << endl;
cout << "p2的年龄: " << *p2.m_Age << endl;
cout << "p3的年龄: " << *p3.m_Age << endl;
}
int main() {
test01();
system("pause");
return 0;
}
5、关系运算符重载
![]()
![]()
#include <iostream>
#include <string>
using namespace std;
//关系运算符重载
class Person {
public:
Person(string name, int age) {
m_Name = name;
m_Age = age;
}
//重载 == 号
bool operator==(Person &p) {
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {
return true;
}
else
return false;
}
//重载 != 号
bool operator!=(Person &p) {
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) {
return false;
}
else {
return true;
}
}
string m_Name;
int m_Age;
};
void test01() {
Person p1("Tom", 18);
Person p2("Tom", 18);
if (p1 == p2) {
cout << "p1和p2是相等的" << endl;
}
else {
cout << "p1和p2是不相等的" << endl;
}
if (!(p1 != p2)) {
cout << "p1和p2是相等的" << endl;
}
else {
cout << "p1和p2是不相等的" << endl;
}
}
int main() {
test01();
system("pause");
return 0;
}
6、函数调用运算符重载
![]()
#include <iostream>
#include <string>
using namespace std;
//函数调用运算符重载
//打印类
class Myprint {
public:
void operator()(string text) {
cout << text << endl;
}
};
//加法类
class Myadd {
public:
int operator()(int num1,int num2) {
return num1 + num2;
}
};
void MyPrint02(string text) {
cout << text << endl;
}
void test01() {
Myprint myFunc;
//仿函数,使用起来非常类似于函数调用
myFunc("hello world"); //对象使用重载的小括号
MyPrint02("hello world"); //函数调用
}
//仿函数非常灵活,没有固定的写法
void test02() {
Myadd myadd;
int ret = myadd(100,100);
cout << "ret = " << ret << endl;
//匿名函数对象,Myadd();(100,100) 重载的函数调用运算符
cout << Myadd()(100, 200) << endl;
}
int main() {
test01();
test02();
system("pause");
return 0;
}