运算符重载

运算符重载

类对象不能直接参与运算,需要对运算符进行重载。
运算符预定义的操作只能针对基本数据类型,但是对于自定义类型,若需要类似的运算符操作,此时也可以重新定义这些运算符的功能,使其支持特定类型,完成特定的操作。
在这里插入图片描述

运算符重载函数的格式

返回值 operator 运算符(参数列表)
{
// 函数体
}

成员函数的格式:

给哪个类重载运算符,就把重载函数定义为哪个类的成员函数。

全局函数的格式:

需要在类内声明全局函数为友元函数。

成员函数版的运算符重载一定比全局函数版的运算符重载少一个参数,成员函数本身提供一个类对象。

运算符重载的目的、要求

目的:让自定义的类也能直接参与运算。
要求:
1、不能创造运算符,必须对已有的运算符重载;
2、不能更改运算符本身的功能,比如加法运算符“+”重载后实现乘法运算;
3、运算符重载本质上也是函数重载,但是不支持函数默认值设定;
4、不能改变重载后的运算符优先级和结合性,也不能改变运算符的操作数和语法结构。

算数运算符的重载

// 成员函数版

#include <iostream>
using namespace std;

class Complex
{
    int real;
    int virt;
public:
    Complex() { }
    Complex(int real, int virt) : real(real), virt(virt) { }
    void show()
    {
        cout << real << "+" << virt << "i" << endl;
    }
    Complex operator+(const Complex &other)
    {
        Complex temp;
        temp.real = this->real + other.real;
        temp.virt = this->virt + other.virt;
        return temp;
    }
};

int main()
{
    Complex com1(3,4);
    Complex com2(5,12);
    cout << "Com1: ";
    com1.show();
    cout << "Com2: ";
    com2.show();

    Complex com3 = com1 + com2;
    cout << "Com3: ";
    com3.show();

    return 0;
}
// 全局函数版

#include <iostream>
using namespace std;

class Complex
{
    int real;
    int virt;
public:
    Complex() { }
    Complex(int real, int virt) : real(real), virt(virt) { }
    void show()
    {
        cout << real << "+" << virt << "i" << endl;
    }
    friend Complex operator+(const Complex &c1, const Complex &c2);
};

Complex operator+(const Complex &c1, const Complex &c2)
{
    Complex temp;
    temp.real = c1.real + c2.real;
    temp.virt = c1.virt + c2.virt;
    return temp;
}

int main()
{
    Complex com1(3,4);
    Complex com2(5,12);
    cout << "Com1: ";
    com1.show();
    cout << "Com2: ";
    com2.show();

    Complex com3 = com1 + com2;
    cout << "Com3: ";
    com3.show();

    return 0;
}

在这里插入图片描述

赋值运算符的重载

#include <iostream>
using namespace std;

class Complex
{
    int real;
    int virt;
public:
    Complex() { }
    Complex(int real, int virt) : real(real), virt(virt) { }
    void show()
    {
        cout << real << "+" << virt << "i" << endl;
    }
    Complex operator-=(const Complex &c1)
    {
        this->real = this->real - c1.real;
        this->virt = this->virt - c1.virt;
        return *this;
    }
};

int main()
{
    Complex com1(3,4);
    Complex com2(5,12);
    cout << "Com1: ";
    com1.show();
    cout << "Com2: ";
    com2.show();

    com2 -= com1;				// 左调右参,com2 调用了混合运算符重载,参数是com1
    cout << "Com2: ";
    com2.show();

    return 0;
}

在这里插入图片描述

如果不手动编写赋值运算符(=)的重载,则赋值运算符重载会被编译器自动添加,见拷贝赋值函数。
当类中出现指针类型的成员变量时,默认的赋值运算符重载函数类名 &operator=(const 类名 &变量),也会产生类似于默认的浅拷贝构造函数的问题。因此也手动编写解决“浅拷贝”问题。

比较运算符的重载

// 成员函数版

#include <iostream>
#include <iomanip>
using namespace std;

class Complex
{
    float a;
public:
    Complex() { }
    Complex(float a):a(a) { }

    bool operator>=(Complex &other)
    {
        return this->a >= other.a;
    }
};

int main()
{
    Complex num1(15);
    Complex num2(6);

    cout << boolalpha << "num1 > num2?" <<  endl << num1.operator >=(num2) << endl;

    return 0;
}
// 全局函数版

#include <iostream>
#include <iomanip>
using namespace std;

class Complex
{
    float a;
public:
    Complex() { }
    Complex(float a):a(a) { }
    friend bool operator>=(Complex &a, Complex &b);		// 友元
};

bool operator>=(Complex &l, Complex &r)
{
    return l.a >= r.a;
}

int main()
{
    Complex num1(15);
    Complex num2(6);

    cout << boolalpha << "num1 > num2?" <<  endl << operator >=(num1, num2) << endl;

    return 0;
}

在这里插入图片描述

() 运算符的重载

强转功能(只有成员函数版)

#include <iostream>
#include <iomanip>
using namespace std;

class Complex
{
    float a;
public:
    Complex() { }
    Complex(float a):a(a) { }
    void show_int();
    operator int()		// operator 类型(),强转功能重载的固定格式,只有成员函数版的重载函数
    {
        return this->a;
    }
};
    
void Complex::show_int()
{
    cout << (int)this->a << endl;		// 这里的 (int) 必须带着
}

int main()
{
    Complex num1(15.7);
//    Complex num2(6);

    cout << "(int)num1.a: ";
    num1.show_int();

    return 0;
}

在这里插入图片描述

伪函数(可重载)

#include <iostream>
#include <iomanip>
using namespace std;

class Complex
{
    float a;
public:
    Complex() { }
    Complex(float a):a(a) { }

    void operator()()		// 重载()运算符,调用函数功能的(),实现一个伪函数
    {
        cout << 250 << endl;
    }
    void operator()(string name)
    {
        cout << name;
    }
};


int main()
{
    Complex num1(15.7);
//    Complex num2(6);

    num1.operator ()("He Yanwei is a ");
    num1.operator ()();

    return 0;
}

在这里插入图片描述

自增自减运算符的重载

// 成员函数版的前自增

#include <iostream>
#include <iomanip>
using namespace std;

class Complex
{
    int a;
public:
    Complex() { }
    Complex(float a):a(a) { }

    void show();
    Complex &operator++()
    {
        ++this->a;
        return *this;
    }
};

void Complex::show()
{
    cout  << ++this->a << endl;
}

int main()
{
    Complex num1(15);
    cout << "++num1.a: ";
    num1.show();

    return 0;
}

在这里插入图片描述
在这里插入图片描述

// 全局函数版后自减

#include <iostream>
#include <iomanip>
using namespace std;

class Complex
{
    int a;
public:
    Complex() { }
    Complex(float a):a(a) { }
    void show();
    friend Complex &operator--(Complex &com, int);		// 必须是 int型 的哑元

};

void Complex::show()
{
    cout  << (this->a)-- << endl;
}

Complex &operator--(Complex &com, int)
{
    static Complex temp = com;   	// 使用 temp 获取自减前的值
    com.a--;
    return temp;  					// 返回自减前的值
}

int main()
{
    Complex num1(17);
    Complex num2 = num1--;

    cout << "num1.a: ";
    num1.show();
    cout << "num2.a--: ";
    num2.show();

    return 0;
}

在这里插入图片描述

插入/提取运算符的重载

<<

// 全局函数实现提取运算符的重载

#include <iostream>
using namespace std;

class Complex
{
    int real;
    int virt;
public:
    Complex() { }
    Complex(int real, int virt) : real(real), virt(virt) { }
    void show()
    {
        cout << real << "+" << virt << "i" << endl;
    }
    friend ostream &operator<<(ostream &out, Complex &com);
};

ostream &operator<<(ostream &out, Complex &com)
{
    out << com.real << "+" << com.virt << "i" << endl;
    return out;
}

int main()
{
    Complex num1(17, 4);
    cout << "num1: ";
    operator<<(cout, num1);			// 会返回一个 cout 继续输出
    // cout 是 ostream 类的类对象,不能自定义,但是可以通过引用 传入函数 再返回
    // cout << a << b;   	// 先输出a,再输出b  	// operator<<(cout, a)<<b
    

    return 0;
}

>>

// 全局函数实现插入运算符的重载

#include <iostream>
using namespace std;

class Complex
{
    int real;
    int virt;
public:
    Complex() { }
    Complex(int real, int virt) : real(real), virt(virt) { }
    void show()
    {
        cout << real << "+" << virt << "i" << endl;
    }
    friend ostream &operator<<(ostream &out, Complex &com);
    friend istream &operator>>(istream &in, Complex &com);
};

ostream &operator<<(ostream &out, Complex &com)
{
    out << com.real << "+" << com.virt << "i" << endl;
    return out;
}
istream &operator>>(istream &in, Complex &com)
{
    in >> com.real >> com.virt;
    return in;
}

int main()
{
    Complex num1(17, 4);
    cout << "num1: ";
    operator<<(cout, num1);

    Complex num2;
    operator>>(cin, num2);
    cout << "num2: ";
    operator<<(cout, num2);

    return 0;
}

在这里插入图片描述

不能重载的运算符

sizeof()
成员访问运算符 .
指针访问运算符 *
域限定符 ::
三目运算符 ? :

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/199589.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于QT的俄罗斯方块游戏设计与实现

基于QT的俄罗斯方块游戏设计与实现 摘要&#xff1a;信息时代正处于高速发展中&#xff0c;而电子游戏已经成为人生活中或不可少的消磨工具之一。科技时代在不断地高速发展中&#xff0c;游戏相关编程设计也随着发展变得越来越重要&#xff0c; 俄罗斯方块游戏是一款古老传遍世…

申请免费的ssl证书

申请网站&#xff1a; https://freessl.cn/ 解密域名&#xff0c;添加cname跳转 下载acme.sh 工具脚本&#xff0c;地址&#xff1a;https://github.com/acmesh-official/acme.sh/wiki/Install-in-China 下载成功之后的acme.sh是一个目录&#xff0c;进去之后才是脚本 执行…

【vue脚手架配置代理+github用户搜索案例+vue项目中常用的发送Ajax请求的库+slot插槽】

vue脚手架配置代理github用户搜索案例vue项目中常用的发送Ajax请求的库slot插槽 1 vue脚手架配置代理2 github用户搜索案例2.1 静态列表2.2 列表展示2.3 完善案例 3 vue项目中常用的发送Ajax请求的库3.1 xhr3.2 jQuery3.3 axios3.4 fetch3.5 vue-resource 4 slot 插槽4.1 效果4…

windows11 phpstudy_pro php8.2 安装redis扩展

环境&#xff1a;windows11 phpstudy_pro php8.2.9 一、命令查看是否安装redis扩展 在对应网站中通过打开&#xff0c;&#xff0c;选择对应的PHP版本&#xff0c;用命令 php -m 查看自己的php 有没有redis扩展 上面如果有&#xff0c;说明已经安装了,如果没有安装&#xff1…

Python加百度语音API实现文字转语音功能

目录 一、引言 二、百度语音API介绍 三、Python实现文字转语音功能 1、安装相关库和工具 2、准备待合成的文字信息 3、调用百度语音API进行合成 四、实验结果与讨论 五、优化与改进 六、结论 一、引言 随着人工智能技术的不断发展&#xff0c;语音合成技术也越来越成…

VT-MSPA1-12-1X/V0直动式比例压力阀放大器

适用于控制不带电位移反馈的比例压力阀、比例流量阀、比例方向阀的控制;差动输入;1个脉冲输出端口;函数发生器;带斜坡时间可调的斜坡生器&#xff08;可上升和下降斜坡&#xff09;; 可调电流调节器;电源带错极保护;LED 电磁铁动作显示;&#xff08;LED 的亮度与流过电磁铁的电…

Python 分解IP段获取所有IP(子网掩码)

需求 192.168.1.0/24,192.168.2.1-192.168.2.254,192.168.3.3 IP段格式已 "," 分割&#xff0c;获取所有IP 注意 1. 判断 IP 是否合规 2. 去除多余的字符&#xff0c;例如空格、换行符 3. 去重 代码 import re import ipaddressdef isIP(ip):p re.compile(^((…

网络运维与网络安全 学习笔记2023.11.28

网络运维与网络安全 学习笔记 第二十九天 今日目标 OSPF汇总之域间路由、OSPF汇总之外部路由、OSPF链路认证 OSPF安全认证之区域认证、OSPF虚链路 OSPF汇总指域间路由 项目背景 企业内网运行多区域的OSPF网络&#xff0c;在R1 上存在多个不稳定的链路 R1上的不稳定链路&a…

4.Spring源码解析-loadBeanDefinitions(XmlBeanDefinitionReader)

第一个点进去 发现是空 肯定走的第二个逻辑了 这里在这里已经给属性设置了值&#xff0c;所以肯定不是空能拿到。 1.ClassPathXmlApplicationContext 总结&#xff1a;该loadBeanDefinitions是XmlBeanDefinitionReader设置xml文件在哪。

Linux 磁盘挂载

一、查看挂载点 df -h 二、查看磁盘信息 fdisk -l 下面红色的这一块就是未分区的磁盘 三、 进行磁盘分区 fdisk /dev/sdb /dev/sdb &#xff1a;是上面fdisk -l查询出来未分区的磁盘地址 根据提示输入m获取命令 四、执行命令&#xff0c;创建一个分区 1、新建分区&#…

代码随想录算法训练营 ---第四十九天

前言&#xff1a; 今天是买卖股票的最佳时机系列&#xff0c;本系列之前在学习贪心思想时做过一些。 第一题&#xff1a; 简介&#xff1a; 本题在读题时我们要注意到几个细节 1.本题股票买卖只有一次。2.我们要在最低点买股票&#xff0c;在最高点卖股票。 我的思路&#…

不小心删除了短信,如何在 Android 上恢复已删除的短信

不小心删除了文字消息在 Android 手机上使用可能会是一种令人痛苦的体验。这些消息可能包含有价值的信息、珍贵的回忆或重要的细节。幸运的是&#xff0c;您可以探索多种方法来恢复这些丢失的消息。在本文中&#xff0c;我们将深入研究可用于检索已删除短信的选项&#xff0c;并…

同质化严重,创新突破难,德佑湿厕纸道阻且长

撰稿|行星 来源|贝多财经 随着大众卫生健康意识的日益加深&#xff0c;作为日常生活必需品的纸类产品也逐步向着精细化、多元化的趋势发展&#xff0c;厨房用纸、婴儿用纸等面向各类特定场景和人群的新品类如雨后春笋般涌出&#xff0c;为市场带来了更多的可能性。 在传统卫…

linux(2)之buildroot使用手册

Linux(2)之buildroot配置toolchain Author&#xff1a;Onceday Date&#xff1a;2023年11月27日 漫漫长路&#xff0c;才刚刚开始… 参考文档&#xff1a; Buildroot - Making Embedded Linux Easy 文章目录 Linux(2)之buildroot配置toolchain1. 构建配置1.1 配置config生成…

探索Python内置类属性__repr__:展示对象的魅力与实用性

概要 在Python中&#xff0c;每个对象都有一个内置的__repr__属性&#xff0c;它提供了对象的字符串表示形式。这个特殊的属性在调试、日志记录和交互式会话等场景中非常有用。本文将详细介绍__repr__属性的使用教程&#xff0c;包括定义、常见应用场景和注意事项&#xff0c;…

深入剖析 Django 与 Flask 的选择之谜

概要 在现代 Web 开发的世界里&#xff0c;Python 作为一门极具灵活性和易用性的编程语言&#xff0c;催生了多个强大的 Web 框架&#xff0c;其中 Django 和 Flask 是最受欢迎的两个。但对于开发者来说&#xff0c;选择哪一个始终是一个令人费解的难题。本文将详细地对比这两…

c++|类与对象(中)

目录 一、类的6个默认成员函数 二、构造函数 2.1概念 2.2七大特性 三、析构函数 3.1概念 3.2特性 四、拷贝构造函数 4.1概念 4.2特性 五、赋值运算符重载 5.1运算符重载 5.2赋值运算符重载 5.3前置和后置重载 六、const成员函数 七、取地址及const取地址操作符重…

如何在Python中操作Redis数据库

目录 一、安装redis-py库 二、连接Redis数据库 三、执行操作 1、设置和获取键值对 2、删除键值对 3、获取列表数据 四、处理数据 1、使用哈希表&#xff08;Hash&#xff09;处理关联数据 2、使用列表&#xff08;List&#xff09;处理有序数据 3、使用集合&#xff…

GoLong的学习之路,进阶,RabbitMQ (消息队列)

快有一周没有写博客了。前面几天正在做项目。正好&#xff0c;项目中需要MQ&#xff08;消息队列&#xff09;&#xff0c;这里我就补充一下我对mq的理解。其实在学习java中的时候&#xff0c;自己也仿照RabbitMQ自己实现了一个单机的mq&#xff0c;但是mq其中一个特点也就是&a…

面试题:MySQL自增主键为什么不是连续的?

文章目录 前言一、自增值存储说明二、自增值修改机制三、 自增值修改时机四、 导致自增值不连续的原因4.1 唯一键冲突4.2 事务回滚4.3 批量写库操作 前言 提出这个问题&#xff0c;是因为在工作中发现 mysql 中的 user 表的 id 默认是自增的&#xff0c;但是数据库存储的结果却…