(本文包含了从基础到中等的运算符重载内容,以及一些在编写代码时可能遇到的问题)
笔记复习
1.运算符重载
以代码实现一个类的两个对象相加为例
#include<iostream>
using namespace std;
class person {
int m_deposit = 1000;
int income = 100;
};
int main() {
person p1;
person p2;
person p3 = p1 + p2;
return 0;
}
我们想要实现p1的m_deposit与p2的m_deposit相加成为p3的m_deposit,p1的income与p2的income相加成为p3的income,但是这时候编译器会提示我们没有与这些操作数匹配的“+”运算符,这个时候就需要重载运算符
可以对已有的运算符重新进行定义,赋予其另外一种功能,以适应不同数据类型
运算符重载实际上是一种特殊的函数重载,我们定义一个函数实现与指定运算符相似但不同的功能,当我们调用这个运算符时转为调用该函数
1)加号运算符重载
作用:实现两个自定义数据类型相加的运算
a.成员函数重载加号运算符
语法:在class内部
类名 operator+(只能接收一个对象的地址){};
ps:因为加号运算符是二元运算符,所以只能对两个数据进行操作,这里类的对象拥有这个函数作为一个数据,传入的对象作为一个数据
#include<iostream>
using namespace std;
class person {
public:
person operator+(person& p) {
person temp;
temp.m_deposit = m_deposit + p.m_deposit;
temp.m_income = m_income + p.m_income;
return temp;
}
int m_deposit = 1000;
int m_income = 100;
};
int main() {
person p1;
person p2;
person p3 = p1+p2;
//成员函数重载本质上是
//person p3=p1.operator+(p2);或person p3.operator+(p1);
cout << p3.m_deposit << endl;
cout << p3.m_income << endl;
return 0;
}
b.全局函数实现加号运算符重载
#include<iostream>
using namespace std;
class person {
public:
int m_deposit = 1000;
int m_income = 100;
};
person operator+(person& p1, person& p2) {
person temp;
temp.m_deposit = p1.m_deposit + p2.m_deposit;
temp.m_income = p1.m_income + p2.m_income;
return temp;
}
int main() {
person p1;
person p2;
person p3 =p1+p2;
//全局函数重载本质上是
//person p3=operator+(p1,p2);
cout << p3.m_deposit << endl;
cout << p3.m_income << endl;
return 0;
}
通过上面的两个例子我们可以知道,重载加号运算符实现两个对象进行相加的操作实际上创建一个函数,在这个函数中创建一个对象,实现这个两个的数据分别对应相加,然后返回这个对象给p3,于是就实现了加号运算符重载,所以运算符重载本质上就是自定义函数的调用
减号运算符重载与加号运算符重载是一样的,两者都是二元运算符,大家可以自己尝试一下
2)左移运算符重载
<<称为左移运算符
语法:
void operator<<(ostream& cout,另一个形参){}
作用:可以自定义输出数据类型
左移运算符是二元运算符,需要两个操作数,一个作为左操作数,一个作为右操作数,而在类中时,类的对象会作为左操作数,但我们要求cout在左边,类的对象在右边,因此无法在使用成员函数重载左移运算符
全局函数重载左移运算符
#include<iostream>
using namespace std;
class person {
public:
int m_deposit = 1000;
int m_income = 100;
};
ostream& operator<<(ostream& cout,person& p) {
cout << p.m_deposit << endl;
cout << p.m_income << endl;
return cout;
}
//使用ostream&可以支持链式调用,当 << 操作完成后,返回输出流对象,这样可以继续使用 <<
//person& p,引用传递,p 是一个引用,使用引用而不是传值,可以避免拷贝整个对象,提高效率。
int main() {
person p1;
cout << p1;
return 0;
}
3)递增运算符重载
作用:通过重载递增运算符,实现自己的整型数据
a.前置递增运算符与后置递增运算符的区别
前置递增运算符是先执行递增操作,再返回递增后的值;后置递增运算符是先保存当前值,再执行递增操作,然后返回递增前的值。通俗来说就是前置递增运算符先递增再执行其他语句,后置递增运算符先执行其他语句再递增。
代码示例:
后置递增运算符
#include<iostream>
using namespace std;
int main() {
int a = 0;
cout << a++ << endl;
cout << a << endl;
return 0;
}
前置递增运算符:
#include<iostream>
using namespace std;
int main() {
int a = 0;
cout << ++a << endl;
cout << a << endl;
return 0;
}
b.后置递增运算符重载
#include<iostream>
using namespace std;
class myinteger {
public:
myinteger() {
m_num = 0;
}
myinteger operator++(int) {
//int用来表明是后置递增,无实际作用
myinteger temp = *this;
m_num++;
return temp;
}
private:
int m_num;
};
void test01() {
myinteger myint;
myint++;
}
int main() {
test01();
system("pause");
return 0;
}
接下来我们试着输出一下我们的整型,注意,这里并不是真正的整型,因此我们需要重载左移运算符。
ostream& operator<<(ostream& cout, myinteger myint) {
cout << myint.m_num;
//由于后置递增运算符返回的是m_num,因此我们这里要输出myint.m_num
return cout;
}
由于重载左移运算符的函数访问了myinteger类的私有成员,因此要在类中进行一次友元声明,完整代码如下:
#include<iostream>
using namespace std;
class myinteger {
friend ostream& operator<<(ostream& cout, myinteger myint);
public:
myinteger() {
m_num = 0;
}
myinteger operator++(int) {
//int用来表明是后置递增,无实际作用
myinteger temp = *this;
m_num++;
return temp;
}
private:
int m_num;
};
ostream& operator<<(ostream& cout, myinteger myint) {
cout << myint.m_num;
return cout;
}
void test01() {
myinteger myint;
myint++;
}
int main() {
test01();
system("pause");
return 0;
}
c.重载前置递增运算符
基本等同于重载后置递增运算符,区别在于重载前置递增运算符时不需要用int占位参数
#include<iostream>
using namespace std;
class myinteger {
friend ostream& operator<<(ostream& cout, myinteger myint);
public:
myinteger operator++() {
++deposit;
myinteger temp = *this;
return *this;
}
private:
int deposit = 999;
};
ostream& operator<<(ostream& cout , myinteger myint) {
cout << myint.deposit;
return cout;
}
int main() {
myinteger myint;
cout << ++myint << endl;;
return 0;
}
4)递减运算符重载
类同于递增运算符,大家自己操作即可
5)关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
案例讲解:一个类中有成员name和age,如果两个对象的name和age相同,那么我们称这两个对象相等,下面用代码实现两个对象的比较
对于关系运算符,返回值为true或者false,因此我们的函数类型应设置为bool
#include<iostream>
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) {
//这里this指针用来解决名称重复问题
//这里this指向的是调用operator==左侧的对象,p是右侧对象,作为参数传入
return true;
}
return false;
}
private:
string m_name;
int m_age;
};
void test01() {
person p1("tom", 18);
person p2("tom", 18);
if (p1 == p2) {
//p1在==左边,因此this指向p1
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 test) {
cout << test << endl;
}
};
void test01() {
myprint myprint;
myprint("hello world");
//实质上是myprint.operator("hello world")
//重载函数调用运算符可以使类对象像函数一样被调用,由于使用起来非常类似于函数调用,因此称为仿函数
}
int main() {
test01();
system("pause");
return 0;
}
仿函数非常灵活,没有固定写法,理论上只要是函数调用能干的事仿函数都可以干,下面我们来看另一个例子,仿函数实现两数相加
#include<iostream>
#include<string>
using namespace std;
class myadd {
public:
int operator()(int num1, int num2) {
return num1 + num2;
}
};
void test02() {
myadd k;
cout << k(100, 100) << endl;
}
int main() {
test02();
system("pause");
return 0;
}
标签:---,p1,int,18,operator,运算符,person,重载 From: https://blog.csdn.net/wlyyywwq/article/details/144206645