C++核心编程之类和对象--C++运算符重载

news2025/2/26 19:35:17

目录

一、运算符重载

二、加号运算符重载

三、左移运算符重载

将类中的成员设置为私有属性,将全局函数设置为友元访问类中的成员

四、递增运算符

五、赋值运算符重载

六、关系运算符重载

七、函数调用运算符重载


一、运算符重载

对已有的运算符进行重新定义,赋予其另一种功能,以适应不同的数据类型

二、加号运算符重载

作用:实现两个自定义数据相加的运算

是自定义的一个函数作用,函数的名称替换成编译器统一提供的名字

运算符重载也可以发生函数重载

函数名 替换成 : operator+

总结注意:

  1. 对于内置的数据类型的表达式的运算符是不可能改变的
  2. 不可以滥用运算符重载

示例:

#include<iostream>

using namespace std;

// 加号运算符重载

class person {

public:

    // 1.成员函数重载

    person operator+(person& p)

    {

        person temp;

        temp.A = this->A + p.A;

        temp.B = this->B + p.B;

        return temp;

    }

int A;

int B;

};

// 2.全局函数重载+号

person operator+(person& p1, person& p2)

{

    // 全局函数的本质调用是:

    // person p3 = operator+(p1,p2);

    person temp1;

    temp1.A = p1.A + p2.A;

    temp1.B = p1.B + p2.B;

    return temp1;

}

// 运算符重载也可以发生函数重载

person operator+(person& p1, int num)

{

    person temp1;

    temp1.A = p1.A + num;

    temp1.B = p1.B + num;

    return temp1;

}



void test01()

{

    person p1;

    p1.A = 10;

    p1.B = 10;

    person p2;

    p2.A = 10;

    p2.B = 10;



    // 成员函数的本质调用是

    person p3 = p1.operator+(p2);

    cout << "成员函数的运算符重载调用后:" << endl << "p3.A:" << p3.A << "\tp3.B:" << p3.B << endl;



    // 全局函数重载的本质调用

    person p4 = operator+(p1,p2);

    cout << "全局函数的运算符重载调用后:" << endl << "p4.A:" << p4.A << "\tp4.B:" << p4.B << endl;



    // 成员函数与全局函数都可以用以下方式直接相加

    //person p6 = p1 + p2;

    //cout << "p3的A的值:" << p3.A << endl << "p3的B的值:" << p3.B << endl;



    //函数重载

    person p5 = p1 + 5;

    cout << "函数重载完后p5的A的值:" << p5.A << endl << "p5的B的值:" << p5.B << endl;



}

int main()

{

    test01();

    return 0;

}

运行结果:

三、左移运算符重载

作用:可以实现输出自定义类型

总结:重载左移运算符配合友元可以实现输出自定义数据类型。

示例:

#include<iostream>

using namespace std;

// 左移运算符重载

class person {

public:

    // 1.成员函数重载左移运算符

    // 利用成员函数重载  左移运算符  p.operator<<(cout)  简化版本是: p<<cout

    // 一般不利用成员函数重载左移运算符,因为无法实现cout在左侧

    // 实现的方式是p << cout

    int A;

    int B;

};

// 2.全局函数重载左移运算符

ostream& operator<<(ostream& cout, person& p)

{

    // ostream 是输出流

    cout << "A = " << p.A << endl << "B = " << p.B << endl;

    return cout;// 返回的还是输出流对象,为了能够链式编程

}

    // cout重载完再返回cout,在重载调用完后还可以继续输出

    // return cout 或者 out 都是可以的, 用引用的方式调用,out本质上是cout的一个别名

void test01()

{

    person p1;

    p1.A = 10;

    p1.B = 10;

    cout << p1 << "Hello World!" << endl;

}

int main()

{

    test01();

    return 0;

}

运行结果:

将类中的成员设置为私有属性,将全局函数设置为友元访问类中的成员

示例:

#include<iostream>

using namespace std;

// 左移运算符重载

class person {

    friend ostream& operator<<(ostream& cout, person& p);

public:

    person(int a,int b)

    {

        this->A = a;

        this->B = b;

    }

private:

    // 1.成员函数重载左移运算符

    // 利用成员函数重载  左移运算符  p.operator<<(cout)  简化版本是: p<<cout

    // 一般不利用成员函数重载左移运算符,因为无法实现cout在左侧

    // 实现的方式是p << cout

    int A;

    int B;

};

// 2.全局函数重载左移运算符

ostream& operator<<(ostream& cout, person& p)

{

    // ostream 是输出流

    cout << "A = " << p.A << endl << "B = " << p.B << endl;

    return cout;// 返回的还是输出流对象,为了能够链式编程

}

// cout重载完再返回cout,在重载调用完后还可以继续输出

// return cout 或者 out 都是可以的, 用引用的方式调用,out本质上是cout的一个别名

void test01()

{

    person p1(100,100);

    cout << p1 << "Hello World!" << endl;

}

int main()

{

    test01();

    return 0;

}

运行结果:

四、递增运算符

 前置递增返回引用,后置递增返回值

示例:

#include<iostream>

#include<math.h>

using namespace std;

// 重载递增运算符



// 自定义整形

class my_Integer {

    friend ostream& operator<< (ostream& cout, my_Integer myint);

public:

    my_Integer()

    {

        my_num = 0;

    }

    // 重置前置++运算符

    my_Integer& operator++()

    {

        my_num++; // 进行++

        return *this;  // 返回自身

        // 返回引用是为了一直对一个数进行操作

    }



    // 重置后置++运算符

    // 后置++不能返回引用是因为不能返回局部变量

    my_Integer  operator++(int) // int 代表是占位参数  可以用于区分  前置和后置递增

    {

        // 先记录

        my_Integer temp = *this;

        // 后递增

        my_num++;

        // 最后将记录的结果返回

        return temp;

    }

private:

    int my_num;

};



// 重载左移运算符

ostream& operator<< (ostream& cout, my_Integer myint)

{

    cout << myint.my_num;

    return cout;

}



// 前置++

void test01()

{

    my_Integer myint;

    cout << "myint1,前置++" << endl << "++(++myprint) = " << ++(++myint) << " myprint = " << myint << endl;

}



// 后置++

void test02()

{

    my_Integer myint2;

    cout << "myint2,后置++" << endl << "(myprint2++) = " << myint2++ << " myprint2 = " << myint2 << endl;

}



int main()

{

    int a = 10;

    cout << "后置++,先输出数据,再++" << endl;

    cout << a++ << endl;

    cout << a << endl;



    int b = 10;

    cout << "前置++,输出++结果" << endl;

    cout << ++b << endl;

    cout << b << endl;



    test01();

    test02();

    return 0;

}

运行结果:

 

五、赋值运算符重载

C++编译器至少给一个类添加4个函数:

  1. 默认构造函数   (无参,函数体为空)
  2. 默认析构函数   (无参,函数体为空)
  3. 默认拷贝构造函数  (对属性进行拷贝)
  4. 赋值运算符  operator=,  对属性进行值拷贝(浅拷贝)

作用:如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题。

示例:

#include<iostream>

#include<math.h>

using namespace std;

// 重载赋值运算符

class person{

public:

    person(int age)

    {

        m_age = new int (age);

    }

    ~person()

    {

        if(m_age!=NULL)

        {

            delete m_age;

            m_age = NULL;
        
        }

    }

    // 重载 赋值运算符

    person & operator=(person & p)// 链式编程的思想,需要返回本身

    {

        // 编译器提供的是两个指针指向同一个地址,在堆区的内容释放的时候只能释放一次,而引起的深,浅拷贝的问题

        // m_age = p.m_age;

        // 编译器提供的是浅拷贝,导致拷贝得到的是堆区地址,堆区的空间只能释放一次,而浅拷贝导致释放两次

 

        // 应该先判断是否有属性在堆区,如果有先释放然后深拷贝

        if(m_age!=NULL){

            delete m_age;

            m_age=NULL;

        }

        // 深拷贝的操作

        m_age = new int(*p.m_age);

        // 返回自身

        return *this;

    }

    int *m_age;

};

 

void test01()

{

    person p(18) ;

    cout<<"p的年龄:"<<*p.m_age<<endl;

    person p1(20);

    cout<<"p1的年龄:"<<*p1.m_age<<endl;

    person p2(10);

    cout<<"p2的年龄:"<<*p2.m_age<<endl;

    cout<<"-------------------------------"<<endl;

 

    cout<<"重载完=后:"<<endl;

    p2=p1=p; // 返回的是自身,可以连等

    cout<<"p的年龄:"<<*p.m_age<<endl;

    cout<<"p1的年龄:"<<*p1.m_age<<endl;

    cout<<"p2的年龄:"<<*p2.m_age<<endl;

}

int main()

{

    test01();

    return 0;

}

运行结果:

 

六、关系运算符重载

作用:重载关系运算符,可以让两个自定义类型对象进行对比操作

示例:

#include<iostream>

#include<math.h>

using namespace std;

// 重载关系运算符

class person {

public:

    person(string name, int age)

    {

        this->name = name;

        this->age = age;

    }

    // 重载==号

    bool operator==(person& p)

    {

        if (this->name == p.name && this->age == p.age)

        {

            return true;

        }

        return false;

    }
    
    // 重载不等号



    bool operator!=(person &p)

    {

        if(this->name == p.name && this->age == p.age)

        {

            return false;

        }

        return true;

    }



    string name;

    int age;

};



void test01()

{

    person p("TOM", 18);

    cout << "p的姓名:" << p.name << " p的年龄:" << p.age << endl;



    person p1("TOM", 20);

    cout << "p1的姓名:" << p1.name << " p1的年龄:" << p1.age << endl;

    person p2("TOM", 18);

    cout << "p2的姓名:" << p2.name << " p2的年龄:" << p2.age << endl;



    cout << "比较p与p1-------------------------" << endl;

    cout << "重载==后的判断:" << endl;

    if (p == p1) {

        cout << "p和p1是相等的" << endl;

    }

    else {

        cout << "p和p1是不相等的" << endl;

    }



    cout << "重载!=后的判断:" << endl;

    if(p!=p1){

        cout<<"p和p1是不相等的"<<endl;

    }else{

        cout<<"p和p1是相等的"<<endl;

    }

    cout << "比较p与p2-------------------------" << endl;

    cout << "重载==后的判断:" << endl;

    if (p == p2) {

        cout << "p和p2是相等的" << endl;

    }

    else {

        cout << "p和p2是不相等的" << endl;

    }

}

int main()

{

    test01();

    return 0;

}

运行结果:

 

七、函数调用运算符重载

  •  函数调用运算符()也可以重载
  •  重载后的使用方式与函数的调用十分相似,因此称为仿函数
  •  仿函数没有固定的写法,非常灵活

示例:

#include<iostream>

#include<math.h>

using namespace std;

// 函数调用运算符重载

class my_print{

public:

    // 重载函数调用运算符

    void operator()(string test)

    {

        cout<<test<<endl;

    }

};

// 仿函数非常灵活,没有固定的写法

 

void myprint02(string test)

{

    cout<<test<<endl;

}

 

// 一个加法的类

class myadd{

public:

    int operator()(int num1,int num2)

    {

        return num1+num2;

    }

};

 

 

void test01()

{

    my_print mprint;

    // 使用起来特别类似函数调用,因此称为仿函数

 

    mprint("hello 重载函数调用运算符");// 重载了()类似于函数

 

    myprint02("函数也可以直接放入字符串");

}

void test02()

{

    myadd myADD;

    int ret = myADD(10,20);

    cout<<"自定义加法类的仿函数结果:"<<ret<<endl;

 

    // 匿名函数对象 myadd(),使用完成后立即自动释放

    cout<<myadd()(100,100)<<endl;

}

int main()

{

    test01();

    test02();

    return 0;

}

运行结果:

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

So-vits-SVC4.1

So-vits-SVC官方项目地址&#xff1a;https://github.com/svc-develop-team/so-vits-svc 中文版&#xff1a;https://github.com/SUC-DriverOld/so-vits-svc-Chinese-Detaild-Documents 教程&#xff1a;https://www.bilibili.com/video/BV1Hr4y197Cy/ 音频处理 1.转mp4/mp…

java修仙基石篇->instanceof子父类检查

instanceof检查子父类&#xff08;或者是否能被强转&#xff09; 作用1&#xff1a;检查某对象是否是某类的子类 如&#xff1a;儿子类继承了父亲类。 检查儿子类对象是否属于父亲类 作用2&#xff1a;检查两个对象是否可以强转 语法&#xff1a; 子类对象 instanceof 父…

相册里的视频怎么提取音频?帮你整理了几个必备的!

有的时候视频中的音频包含重要信息&#xff0c;如对话、旁白、音乐等。提取音频不仅可以节省存储空间&#xff0c;还方便对这些信息进行单独处理和利用。那么如何提取音频呢&#xff1f;下面介绍了3种方法~ 方法一&#xff1a;直接使用手机相册自带功能 1、打开手机相册&#…

【前端】JQ插件实现打印功能

1、准备工作 下载三个js文件&#xff1a;jquery.jqprint-0.3.js、jquery-migrate-1.2.1.min.js、jquery-1.11.3.min.js&#xff0c; 下载地址&#xff1a;https://download.csdn.net/download/qq_25285531/88492425 2、实现效果 点击“打印指导单”&#xff0c;调起打印机&a…

麻醉科常用评估量表汇总,建议收藏!

根据麻醉科医生的量表使用情况&#xff0c;笔者整理了10个麻醉科常用量表&#xff0c;可在线评测直接出结果&#xff0c;可转发使用&#xff0c;可生成二维码使用&#xff0c;可创建项目进行数据管理&#xff0c;有需要的小伙伴赶紧收藏&#xff01; 1.维持液体计算 维持液体是…

网络安全专业大学生一定要考的证书

在数字经济时代&#xff0c;网络安全成为了至关重要的一环&#xff0c;社会对网络安全技术人才的需求也在不断增长。网络安全行业以其独特的薪酬、福利和发展机遇吸引了众多优秀人才。 在市场上&#xff0c;大多数国家认可的证书都需要一定的工作经验才能获得。然而&#xff0c…

基于OSPF的MGRE实验

目录 题目&#xff1a;基于OSPF的MGRE实验 步骤一&#xff1a;拓扑搭建 步骤二&#xff1a;地址配置 步骤三&#xff1a;公网通 步骤四&#xff1a;MGRE VPN配置 中心站点&#xff1a;R1 分支站点&#xff1a; 步骤五&#xff1a;基于MGRE环境下的OSPF配置 步骤六&#xff1…

软件测试/测试开发丨利用ChatGPT自动生成架构图

点此获取更多相关资料 简介 架构图通过图形化的表达方式&#xff0c;用于呈现系统、软件的结构、组件、关系和交互方式。一个明确的架构图可以更好地辅助业务分析、技术架构分析的工作。架构图的设计是一个有难度的任务&#xff0c;设计者必须要对业务、相关技术栈都非常清晰…

【JAVA学习笔记】55 - 集合-Map接口(难点)

Map接口 一、Map接口的特点&#xff08;难点&#xff09; 难点在于对Node和Entry和EntrySet的关系 注意:这里讲的是JDK8的Map接口特点 Map java 1) Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value&#xff08;双列&#xff09; 2) Map中的key和value 可以…

物联网整体框架有哪些层面?

物联网是当前非常火热的话题&#xff0c;各个行业对物联网的关注和投入力度也很大&#xff0c;一些互联网巨头都在紧锣密鼓的布局物联网产业&#xff0c;抢占市场先机。 物联网的整体构架大致可以分为以下四个层面&#xff1a; 1.感知识别层 感知层是物联网整体架构的基础&…

Elasticsearch:使用 Elasticsearch 进行词汇和语义搜索

作者&#xff1a;PRISCILLA PARODI 在这篇博文中&#xff0c;你将探索使用 Elasticsearch 检索信息的各种方法&#xff0c;特别关注文本&#xff1a;词汇 (lexical) 和语义搜索 (semantic search)。 使用 Elasticsearch 进行词汇和语义搜索 搜索是根据你的搜索查询或组合查询…

【0基础学Java第五课】-- 方法的使用

5. 方法的使用 5.1 什么是方法5.2 方法定义5.3方法调用的执行过程例题&#xff1a;求n的阶乘和 5.4 实参和形参的关系&#xff08;重点&#xff09;5.5 没有返回值的方法5.6 方法重载5.7 方法签名5.8 递归5.9 递归练习按顺序打印一个数字的每一位(例如 1234 打印出 1 2 3 4)递归…

【Python语言速回顾】——爬虫基础知识

目录 一、爬虫概述 1、准备工作 2、爬虫类型 3、爬虫原理 二、爬虫三大库 1、Requests库 2、BeautifulSoup库 3、Lxml库 一、爬虫概述 爬虫又称网络机器人&#xff0c;可以代替人工从互联网中采集、整理数据。常见的网络爬虫主要有百度公司的Baiduspider、360公司的36…

电脑MSVCP120.dll丢失的解决办法,快速有效解决策略

在日常电脑使用过程中&#xff0c;我们可能会遇到一种情况&#xff0c;即打开某些程序或者游戏时&#xff0c;突然弹出一个错误提示&#xff0c;告诉我们"找不到MSVCP120.dll"文件&#xff0c;使得程序不能正常运行。本篇文章就带大家了解MSVCP120.dll以及MSVCP120.d…

springmvc 讲解(2)

系列文章目录 springmvc讲解&#xff08;1 &#xff09;点击此处即可 文章目录 系列文章目录一、Springmvc发送数据1、快速跳转页面1.1 开发模式讲解1.2 jsp简述1.3 页面跳转控制1.4 转发和重定向 2、返回json数据2.1 ResponseBody 注解2.2 RestController注解 3、访问静态资源…

Rust编程基础之6大数据类型

1.Rust数据类型 在 Rust 中, 每一个值都属于某一个 数据类型&#xff08;data type&#xff09;, 这告诉 Rust 它被指定为何种数据&#xff0c;以便明确数据处理方式。我们将看到两类数据类型子集&#xff1a;标量&#xff08;scalar&#xff09;和复合&#xff08;compound&a…

【Git】Git暂存使用

当我们正常使用Git切换分支时&#xff0c;会出现以下提示&#xff08;请在切换分支之前提交您的更改或隐藏它们&#xff09;&#xff1a; Please commit your changes or stash them before you switch branches. 这是由于你现有分支上有修改还没有commit&#xff0c;而你又选择…

汽车配件商城小程序制作 | 汽车配件售卖,高门槛但高利润

通过汽车配件商城小程序给别人的供货&#xff0c;利润可高达60%&#xff0c;但甚少有人关注汽车配件销售的行业。具体情况是怎么样的呢&#xff0c;下面给大家简单分析。 据数据显示&#xff0c;国内有4亿多辆汽车&#xff0c;这些汽车坏了要修&#xff0c;也要偶尔进行保养&am…

6个免费可商用的高清图片素材网站

找免费课商用图片就上这6个网站&#xff0c;高质量无水印&#xff0c;赶紧收藏&#xff01; 1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYwNDUx 网站主要为新手设计师提供免费素材&#xff0c;这些素材的质量都很高&#xff0c;类别也很多&#xff0c;像平面、UI、电…

递归函数实现省市区多级联动搜索帮助

1、需求背景 当程序中有互为层级的字段&#xff0c;需要使用搜索帮助时&#xff0c;可以通过多次调用搜索帮助来实现。比如在程序中需要填写省市区三级地址 2、实现方式 2.1、平铺直叙 程序的搜索帮助&#xff0c;通常使用F4IF_INT_TABLE_VALUE_REQUEST来实现。多级的搜索帮…