C++运算符号重载详解

简介: C++运算符号重载详解

接下来我们用来举例的代码

class Date{
int year;
int month;
int day;
};



1)=   重载

很多人认为 在不是初始化的时候利用 =  号是拷贝构造函数实现的,其实不然,这个是系统默认的  =  实现的,但它也有弊端,就是浅拷贝(指针等不是重新开辟的空间,而是单纯的拷贝,会导致同一块空间被反复使用和释放),因此想要实现深拷贝就需要我们自己写一个函数的重载。接下来我们先看代码

Date& Date::operator=(const Date& d){ //引用返回值  operator  重载符号  参数
  _year = d._year;
  _month = d._month;       //返回引用是因为要实现 a=b=c
  _day = d._day;           //const是因为这个是拷贝是不会改变d的,这样可以保证数据不被意外改动
  return *this;             //this是指针要解引用才能得到真正的Date
}

现在考虑重载函数的命名,我们要知道函数的重载有两种方式,一个是写在类里面作为成员函数的方法,一个是写在类外实现的,但是有一个要求,就是参数的顺序要对应运算符的参数顺序。=  又是一个特例,因为类里面已经有一个   =   的默认系统实现了,如果我们写在类外,就不能覆盖类内的成员函数,导致程序出现二义性。

里面还有一个细节在括号()里面第一个默认参数是this ,因此符合了参数的顺序关系

2)>    重载

返回值为bool,因为>符号只需要结果,结果只有两种:真和假

这个符号可以用成员函数和在类外实现,因为系统没有默认的<符号重载

成员函数实现:

bool Date::operator>(const Date& d) {
  if (_year > d._year)
    return true;
  if (_year < d._month)
    return false;
  if (_month > d._month)
    return true;
  if (_month < d._month)
    return false;
  if (_day > d._day)
    return true;
  else return false;
}

类外实现

bool operator>(const Date& b,const Date& d) {
  if (b._year > d._year)
    return true;
  if (b._year < d._month)
    return false;
  if (b._month > d._month)
    return true;
  if (b._month < d._month)
    return false;
  if (b._day > d._day)
    return true;
  else return false;
}
3)  >=    重载

返回值为bool,因为>=符号只需要结果,结果只有两种:真和假

类内重载

bool Date::operator >= (const Date& d) {
  if (_year > d._year)
    return true;
  if (_year < d._month)
    return false;
  if (_month > d._month)
    return true;
  if (_month < d._month)
    return false;
  if (_day >= d._day)
    return true;
  else return false;
}

类外实现

bool operator >= (const Date& b,const Date& d) {
  if (b._year > d._year)
    return true;
  if (b._year < d._month)
    return false;
  if (b._month > d._month)
    return true;
  if (b._month < d._month)
    return false;
  if (b._day >= d._day)
    return true;
  else return false;
}
4)<   重载

如果使用上面相同的方法我们不免太无趣,我们这里使用一个偷懒的方法———复用

bool Date::operator < (const Date& d) {
  if (*this >= d)
    return false;
  return true;
}

类外也同样复用即可

5)<=   重载
bool Date::operator <= (const Date& d) {
  if (*this > d)
    return false;
  return true;
}
6)==   符号

这个返回值同样为bool,因为结果只有真假之分

bool Date::operator==(const Date& d) {
  if (_year == d._year  && _month == d._month && _day == d._day)
    return true;
  return false;
}
7)+  重载

因为要支持   a=a+b=a+c;因此返回值应该为临时拷贝或者引用

Date Date::operator+(int day) {
  Date temp = *this;
  temp._day += day;
  while (temp._day > GetMonthDay(temp._year, temp._month)) {
    temp._day -= GetMonthDay(temp._year, temp._month);
    temp._month++;
    if (temp._month > 12) {
      temp._year++;
      temp._month -= 12;
    }
  }
  return temp;
}
8)+=   重载

因为要支持   a=a+b=a+c;因此返回值应该为引用,不能为临时拷贝,因为无法实现(a+=7)++;

Date& Date::operator+=(int day) {
  *this = *this + day;
  return *this;
}
9) <<  流输出重载

首先我们要知道返回值,我们知道这个是允许连续操作的,例如:cout<<a<<b;因此返回值应该是cout,而cout的返回类型是ostream,我们返回它的引用即可。

重要:因为它的第一个参数是cout,如果使用类内重载,默认第一个参数是类Date,因此无法达到我们想要的效果,我们只能使用类外重载。

ostream& operator<<(ostream& out,Date a){
out<<a._year<<a.month<<a.day<<endl;
return out;
}
10)  >>  输入流重载

首先我们还是考虑返回值,我们可以通过查找文献得知,>>的返回值是支持连续操作的istream类型,因为参数的顺序原因我们还是只能使用类外函数来实现。

istream& operator>>(istream& in,Date a){
in>>a._year>>a.month>>a.day<<endl;
return in;
}
总结:

细节:类内成员函数方式重载的第一个参数是this指针,因为输入输出流的第一个参数是iostream,所有无法用成员函数的方式重载,而赋值符号重载 = 因为系统有一个默认的符号重载,所以无法以全局函数方式重载。其次我们要考虑运算符支持的操作,从而考虑返回类型。

授人以鱼不如授人以渔,我虽然没有列举出来所有的重载,类型,但我将重载如何入手以及需要的注意点和细节全部传授出来了,只要你认真阅读本文章,是能掌握运算符重载的。

相关文章
|
6月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
300 77
|
6月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
218 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
6月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
156 12
|
6月前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
109 9
|
6月前
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
175 7
|
6月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
273 5
|
6月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
160 5
|
10月前
|
C++
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。
|
12月前
|
NoSQL 编译器 Redis
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
|
12月前
|
NoSQL Redis C++
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决