首页 > 其他分享 >重载运算符详解

重载运算符详解

时间:2023-10-13 10:22:34浏览次数:28  
标签:函数 Point int 运算符 ++ 详解 重载

重载运算符详解

1.概念

  运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该运算符时就调用此函数来行使运算符功能。这个函数叫做运算符重载函数(常为类的成员函数)。   用函数的方式实现了(+ - * / []数组 && || 逻辑 等)运算符的重载。根据需求决定重载那些运算符,用到的时候再百度案例即可。

2.运算符重载的基本格式

   返回值类型 类名::operator重载的运算符(参数表)    {    ……    }

   operator是关键字,它与重载的运算符一起构成函数名。

3.运算符重载的两种方法

二元运算符重载

1.类内重载

#include <iostream>
using namespace std;

class Point{
public:
   Point(){};
   Point (int x, int y): x(x),y(y) {};
   Point operator+(const Point &b){ //类内重载,运算符重载函数作为类的成员函数
       Point ret;
       ret.x = this->x + b.x;
       ret.y = this->y + b.y;
       return ret;
  }
   int x,y;
};

int main() {
   Point a(2,4),b(5,3);
   Point c = a + b;      //这里c++编译器会,自动去找 + 运算符的重载函数
cout<< "x :" << c.x << endl;
   cout<<"y :" << c.y << endl;
}
12345678910111213141516171819202122

运行结果:x : 7     y : 7

重点:运算符重载是类内重载时,运算符重载函数作为类的成员函数,以上述代码为例 a + b 相当于 a 对象调用+方法并且传入参数时 b 对象。

2.类外重载(用友元函数的方法实现)

#include <iostream>
using namespace std;

class Point{
public:
   Point(){};
   Point (int x, int y): x(x),y(y) {};
   friend Point operator+(const Point &, const Point &);   //声明类的友元函数
   int x,y;
};

Point operator+(const Point &a,const Point &b){//类外重载,运算符重载函数作为类的友元函数
   Point ret;
   ret.x = a.x + b.x;
   ret.y = a.y + b.y;
   return ret;
}

int main() {
    Point a(2,4),b(5,3);
   Point c = a + b;
cout<< "x :" << c.x << endl;
   cout<<"y :" << c.y << endl;
}
123456789101112131415161718192021222324

一元运算符重载(注意:返回值当左值得时候,返回的是一个引用)

1.插入运算符重载>> and 提取运算符重载<<   以提取运算符重载<<为例,cout 是 ostream 类的对象。ostream 类和 cout 都是在头文件 中声明的。ostream 类将<<重载为成员函数。

下面我们重载 << 使用cout输出a对象

#include <iostream>
using namespace std;

class Point{
public:
   Point(){};
   Point (int x, int y): x(x),y(y) {};
   friend ostream &operator<<(ostream &out , const Point &a);  //因为 << 是C++提供的类,我们无法访问,只能用友元函数。
private:
   int x,y;
};

//<< 运算符重载的函数实现   ostream是输入输出流的类
ostream &operator<<(ostream &out , const Point &a){
   out << "<Point>( " << a.x << ", " << a.y << ")";
   return out;
}

int main() {

   cout << c<< endl;    //直接输出类会报错,需要上面的 << 运算符重载
}

输出结果:< Point>( 7, 7) 重点:另外应该会有人对ostream &operator<<(ostream &out , const Point &a)函数感到疑惑,首先在重载<<时,返回值类型是ostream&, 第一个参数也是ostream& 。也就是说,表达式cout<<c的返回值仍是 cout,所以cout<<c<<endl;才能成立。

2.前置运算符重载++ and 后置运算符重载++ 重点:为区别前置和后置运算符,C++编译器要求,需要在后置运算符重载函数中加参数“int”,这个类型在此除了以示区别之外并不代表任何实际含义;如果不加,编译器无法区分是前置++,还是后置++,导致报错。

#include <iostream>
using namespace std;

class Point{
public:
   Point(){};
   Point (int x, int y): x(x),y(y) {};
   friend Point operator+(const Point &, const Point &);
   friend ostream &operator<<(ostream &out , const Point &a);
   Point& operator++(){ //前置++运算符,需要引用返回,不需要参数。返回自增后的值,且返回的是一个左值
       this->x ++;
       this->y ++;
       return *this;
  }
    //const 修饰返回值不能修改  
   const Point operator++(int){//后置++,不需要引用返回,需要参数区分。返回自增前的值,且返回的是一个右值
       Point temp(x,y);       //因为后置++,是先使用,后自++,所以这里要保存一个临时值,再++,返回的是临时值。
       this->x ++;
       this->y ++;
       return temp;
  }
private:
   int x,y;
};

Point operator+(const Point &a,const Point &b){
   Point ret;
   ret.x = a.x + b.x;
   ret.y = a.y + b.y;
   return ret;
}

ostream &operator<<(ostream &out , const Point &a){
   out << "<Point>(" << a.x << " , " << a.y << ")";
   return out;
}


int main() {
   Point a(2,4),b(5,3);
   Point c = a + b;
   cout << c << endl;
   c++;
   cout << c << endl;
   ++c;
   cout << c << endl;
}

3.=等号运算符重载 C++中,对类对象进行操作时,我们就不能只是简简单单地,对类对象用=进行操作。 当我们没有自己设计等号运算符的重载函数,编译器会自动生成一个浅拷贝的赋值运算符的重载函数。 浅拷贝:只是简单地将一个对象的内存数据赋值给另一个对象,如果这个对象成员变量引用了外部资源时(new),那么这两个对象的成员变量都指向这个空间,当这两个对象生存周期结束时,进行析构,那么就会崩溃,对同一块内存我们delete了两次。

#include <iostream>
using namespace std;

class  Name
{
public:

  //main函数中的问题   Name obj2 = obj1;  
//解决方案: 手工的编写拷贝构造函数 使用深copy
Name(const Name& obj)
{
m_len = obj.m_len;
m_p = (char *)malloc(m_len + 1);
strcpy(m_p, obj.m_p);
}

  //等号运算符重载函数
Name& operator=(Name &obj)  
{
//1.先释放旧的内存
if (this->m_p != NULL)
{
delete[] m_p;
m_len = 0;
}
//2.根据obj分配内存大小
this->m_len = obj.m_len;
this->m_p = new char [m_len+1]; //加1,结束符'\n'。

//3.把obj赋值
strcpy(m_p, obj.m_p);  //字符串的拷贝函数
return *this;
}

~Name()    //析构函数
{
if (m_p != NULL)
{
free(m_p);
m_p = NULL;
m_len = 0;
}
}
protected:
private:
char *m_p ;
int m_len;
};

void main()
{

Name obj1("abcdefg");
Name obj2 = obj1;  //C++编译器提供的 默认的copy构造函数 浅拷贝,需要手工编写构造函数
Name obj3("obj3");

obj1 = obj2 = obj3;    //调用等号运算符重载
cout<<"hello..."<<endl;
system("pause");
return ;
}

标签:函数,Point,int,运算符,++,详解,重载
From: https://www.cnblogs.com/wenyutao1/p/17761423.html

相关文章

  • Node系列 — v8引擎堆内存详解
    参考:https://juejin.cn/post/6963170647207837710v8的堆内存限制Node程序中javascript的使用内存是有限制的,注意这个内存是指堆内存,在v8中,所有的js对象都存在堆中。在实际应用中不小心触碰到这个边界,进程就会退出。64位系统下为1.4GB,32位系统下为0.7GB。Node是基于v8......
  • Oracle数据库导入、导出详解
    Oracle11g数据库导入导出方式传统方式【exp(导出)和(imp)导入】数据泵方式【expdp导出和(impdp)导入】第三方工具【PL/sqlDevelpoer】一、什么是数据库导入导出?Oracle11g数据库的导入/导出,就是我们通常所说的Oracle数据的还原/备份。 数据库导入:把.dmp格式文件从本地导入到......
  • Python 列表详解:从基础到进阶
    Python是一种广泛使用的高级编程语言,它的设计强调代码的可读性和简洁的语法。Python支持多种编程范式,包括过程、面向对象和函数式编程。在Python中,列表是一种非常重要的数据类型,它可以包含各种类型的元素,如数字、字符串和其他列表。本文将详细介绍Python列表的基础和进阶用法。【基......
  • 第四节:Redis数据持久化机制(备份恢复)、缓存淘汰策略、主从同步原理、常见规范与优化
    一.数据持久化 1. 含义Redis提供了RDB和AOF两种持久化方式,默认开启的是RDB,如果需要AOF,需要手动修改配置文件进行开启。RDB:是一种对Redis存在内存中的数据周期性的持久化机制,将内存中的数据以快照的形式硬盘,实质上是fork了一个子进程在执行数据存储,采用的是二进制压......
  • 软件测试|Linux三剑客之sed命令详解
    简介sed(StreamEditor)是一款流式文本编辑器,在Linux和类Unix系统中广泛使用。它的设计目的是用于对文本进行处理和转换,可以用于替换、删除、插入、打印等操作。sed命令通过逐行处理文本,允许您使用简单的命令来编辑大量文本数据。本文将详细介绍sed命令的基本用法和一些常......
  • 软件测试|Linux三剑客之grep命令详解
    简介grep是一款在Linux和类Unix系统中广泛使用的文本搜索工具。它的名字来源于GlobalRegularExpressionPrint(全局正则表达式打印),它的主要功能是根据指定的模式(正则表达式)在文本文件中搜索并打印匹配的行。grep非常强大且灵活,可以用于日志分析、文件过滤、代码搜索等多......
  • 软件测试|Linux三剑客之awk命令详解
    简介awk是一种强大的文本处理工具,在Unix和类Unix系统中广泛使用。它允许您在文本文件中进行复杂的数据处理和格式化输出。awk的名字是根据它的三位创始人Aho、Weinberger和Kernighan姓氏的首字母命名的。本文将详细介绍awk命令的基本用法和一些常见的用例。awk基本语......
  • C#(7):操作符详解
    使用default操作enum类型时,最好将一个选项赋值为0设计模式:依赖注入模式,将紧耦合调至松耦合checked{}检测溢出unchecked不检测delegate声明匿名变量,不常用unsafe声明不安全变量&取地址操作符,*取引用符号,等同(*pStu).scorec#中所有数据类型都由object所派生,,任何......
  • C++ - 运算符
    3运算符作用:用于执行代码的运算本章我们主要讲解以下几类运算符:运算符类型作用算术运算符用于处理四则运算赋值运算符用于将表达式的值赋给变量比较运算符用于表达式的比较,并返回一个真值或假值逻辑运算符用于根据表达式的值返回真值或假值3.1算术......
  • WiFi无线通信技术详解
    WiFi技术是一种短距离无线通信技术,也称为IEEE802.11b标准。它使用2.4GHz附近的频段,可以在不需要许可的情况下进行通信。WiFi技术的最大优点是传输速度快,可达到11Mbit/s,同时它的覆盖范围也很广,可以与各种IEEE802.11直接序列扩频(DSSS)设备兼容。WiFi无线网络结构包括Adhoc和Infras......