运算符重载时C++中的一大特性,在C中我们可以直接去用“+、-、*、/、++、--”等运算符,可以运用两个赋值的变量进行运算。但是在C++中引入了对象的概念,使得对象无法通过运算符进行运算,由此引入了运算符重载。
下面我们队引入的概念及运算符重载依次进行阐述。
------------------------------------------------------------------------------------------------------------------------------------------
类和对象
类:通过观察事物,我们对属性和行为整合在一起来描述一类事物的自定义数据类型,在C++中把这种自定义的数据类型成为类。
对象:用类这个自定义的数据类型定义出来的变量称为对象。
那么,怎样去理解属性和行为呢?
我们不妨去设定一个场景,一个学生,活灵活现的学生,他有哪些属性、行为呢?
学生,属性就是属于他的固有情况,或者说基本情况,一般会隐藏起来,不难得出:
属性:学号、姓名、班级、家庭住址、年龄、性别、考试成绩......
同样的,他的行为是什么呢?想想学生能干什么:
行为:能上课、能学习、能睡觉、能吃饭、能考试......
这样我们就把学生这个类的属性和行为进行了整合得到一个学生的类,那么怎样去理解类和对象的关系呢?定义这样一句话:
类是对象的抽象,对象是类的具体实例。
学生这个整体,我们把他成为类,用类去定义一个具体的学生比如“张三”,“张三”就是具体的对象了,这样是不是就很好理解了呢。
那么,过渡完了...进入正题
运算符重载
我把运算符重载的基础知识点总结放在下面了↓
一般来说,进行运算符重载有两种方法:
成员函数重载:成员函数有this指针,所以只需要传一个操作数就可以,因为隐藏的this就可以代表一个操作了!
友元函数重载:因为没有this指针,所以参与运算的操作是都要做为参数传进来,参数个数会比成员函数重载多一个!
做一个实例:实现复数的加法运算,两种方法
#include <iostream>
using namespace std;
//复数的定义格式 a+bi
class CComplex
{
public:
CComplex(int _real = 0, int _img = 0):real(_real),img(_img)
{
cout << "CComplex的默认构造函数" << endl;
this->real = _real;
this->img = _img;
}
~CComplex()
{
cout << "CComplex的析构函数" << endl;
}
void show()
{
cout << this->real << "+" << this->img << "i" << endl;
}
//方法一:成员函数重载
CComplex operator+(CComplex& b)
{
CComplex c;
c.real = this->real + b.real;
c.img = this->img + b.img;
return c;
}
//方法二的友元
friend CComplex operator+(CComplex& a, CComplex& b);
private:
int real; //实部
int img; //虚部
};
//方法二:友元函数重载
CComplex operator+(CComplex& a, CComplex& b)
{
CComplex c;
c.real = a.real + b.real;
c.img = a.img + b.img;
return c;
}
int main()
{
CComplex a(5, 2);
CComplex b(2, 1);
CComplex c;
// c = a.operator+(b);
c = operator+(a, b);
c.show();
return 0;
}
运行结果为:
CComplex的默认构造函数
CComplex的默认构造函数
CComplex的默认构造函数
CComplex的默认构造函数
CComplex的析构函数
CComplex的析构函数
7+3i
如果operator运算重载函数非友元函数,并且是类的成员函数,就存在this指针,那么如果是两个对象进行运算时候,那么参数只需要传一个对象的。因为本身自带一个对象
如果operator运算符重载函数是友元函数,那么知道友元函数不存在this指针,所以传入的是两个对象。
做第二个实例:实现++运算符
#include <iostream>
using namespace std;
class CComplex
{
public:
CComplex(int _real = 0, int _img = 0)
{
this->real = _real;
this->img = _img;
}
~CComplex()
{
}
void show()
{
cout << "运算结果为:" << this->real << "+" << this->img << "i" << endl;
}
//成员函数重载++a;
CComplex& operator++()
{
++this->real;
++this->img;
return *this;
}
//成员函数重载a++,参数加个int区分
CComplex& operator++(int)
{
CComplex c = *this;
++this->real;
++this->img;
return c;
}
friend CComplex& operator++(CComplex& a);
friend CComplex& operator++(CComplex& a, int);
private:
int real;
int img;
};
CComplex& operator++(CComplex& a)
{
++a.real;
++a.img;
return a;
}
CComplex& operator++(CComplex& a, int)
{
CComplex c = a;
++a.real;
++a.img;
return c;
}
int main()
{
CComplex a(2, 3);
CComplex c;
//a++的调用
(a.operator++()).show();
//++a的调用
operator++(a).show();
// (++a).show();
return 0;
}
问题来了,函数返回值类型什么时候使用引用呢?什么时候不使用引用?
answers:形参是实参的引用,并且最后返回的还是实参本身的话,就用引用!
如果返回的是一个局部的对象,就不能使用引用了!
需要注意的是,不是所有的运算符都可以进行友元+成员函数重载;例如 <<运算符就只能通过友元函数重载实现!
留给读者两个问题:
<1>.自我去实现一下<<运算符的重载,感受一下它只能通过友元函数的实现
<2>.如果第一个问题解决了,尝试一下进阶版的:封装一个string的类!
--------------------------------------------------------我是分割线------------------------------------------------------------end
写在文末:C++比较抽象,在学习时一定要对基础的定义和格式进行熟悉再熟悉,对于一些比较抽象的事物了解后最好能自我实现一下,辅助思维导图进行学习。做到:
多交流
多动手
多思考
多总结
多复习
总的来说,多敲,敲了想,想完继续敲!
you can make it~