【第四天]C++高级类和对象:运算符重载、string类和智能指针的深度解析

news2024/10/2 14:24:24

一、运算符重载 

        运算符重载 是对已有的运算符 指定新功能,不能创建新运算符。

运算符重载关键字operator

语法:operator@        (@表示被重载的运算符)

思路:

1、弄懂 函数的参数中参数个数取决于运算符是一元还是二元

2、弄懂运算符左边的运算对象 是类的对象 还是其他.

        类的对象:全局函数实现(一元是一个参数,二元是两个参数)

                          成员函数实现(一元没有参数,二元是一个参数)--推荐

        其他:只能是全局函数实现 

1、可以重载的运算符

2、重载<<运算符(全局函数实现) 

3、重载输入>>运算符 

 4、重载加法运算符+(全局函数实现)

#include<iostream>
#include<string>
using namespace std;
class Person
{
	friend ostream& operator<<(ostream& out, Person ob);
	friend istream& operator>>(istream &in, Person &ob);
	friend Person operator+(Person ob1, Person ob2);
private:
	int num;
	string name;
	float score;
public:
	Person() {}
	Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
};
ostream& operator<<(ostream& out, Person ob)
{
	out << ob.num << " " << ob.name << " " << ob.score << endl;
	return out;
}
istream& operator>>(istream &in, Person &ob)
{
	in >> ob.num >> ob.name >> ob.score;
	return in;
}
Person operator+(Person ob1, Person ob2)
{
	Person tmp;
	tmp.num = ob1.num + ob2.num;
	tmp.name = ob1.name + ob2.name;
	tmp.score = ob1.score + ob2.score;
	return tmp;
}
int main(int argc, char* argv[])
{
	Person lucy(100, "lucy", 85.5f);
	Person bob(101, "bob", 95.5f);
	Person tom(102, "tom", 75.5f);
	cout << lucy + bob + tom << endl;
	return 0;
}

5、重载加法运算符+(成员函数实现 推荐)

#include<iostream>
#include<string>
using namespace std;
class Person
{
	friend ostream& operator<<(ostream& out, Person ob);
	friend istream& operator>>(istream &in, Person &ob);
private:
	int num;
	string name;
	float score;
public:
	Person() {}
	Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
	//成员函数重载+
	Person operator+(Person ob)
	{
		Person tmp;
		tmp.num = this-> num + ob.num;
		tmp.name = this-> name + ob.name;
		tmp.score = this-> score + ob.score;
		return tmp;
	}
};
ostream& operator<<(ostream& out, Person ob)
{
	out << ob.num << " " << ob.name << " " << ob.score << endl;
	return out;
}
istream& operator>>(istream &in, Person &ob)
{
	in >> ob.num >> ob.name >> ob.score;
	return in;
}	
int main(int argc, char* argv[])
{
	Person lucy(100, "lucy", 85.5f);
	Person bob(101, "bob", 95.5f);
	Person tom(102, "tom", 75.5f);
	cout << lucy + bob + tom << endl;
	return 0;
}

6、重载==运算符(成员函数实现 )

#include<iostream>
#include<string>
using namespace std;
class Person
{
	friend ostream& operator<<(ostream& out, Person ob);
	friend istream& operator>>(istream &in, Person &ob);
private:
	int num;
	string name;
	float score;
public:
	Person() {}
	Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
	//成员函数重载==
	bool operator==(Person& ob)
	{
		if (num == ob.num && name == ob.name && score == ob.score)
			return true;
		return false;
	}
};
ostream& operator<<(ostream& out, Person ob)
{
	out << ob.num << " " << ob.name << " " << ob.score << endl;
	return out;
}
istream& operator>>(istream &in, Person &ob)
{
	in >> ob.num >> ob.name >> ob.score;
	return in;
}	
int main(int argc, char* argv[])
{
	Person lucy(100, "lucy", 85.5f);
	Person bob(101, "bob", 95.5f);
	if (lucy == bob)
	{
		cout << "相等" << endl;
	}
	else
	{
		cout << "不相等" << endl;
	}
	return 0;
}

7、重载++运算符

(1)重载后置++

++a(前置++),它就调用operator++(a)

a++(后置++),它就会去调用operator++(a,int)//int为占位参数。

#include<iostream>
#include<string>
using namespace std;
class Person
{
	friend ostream& operator<<(ostream& out, Person ob);
	friend istream& operator>>(istream &in, Person &ob);
private:
	int num;
	string name;
	float score;
public:
	Person() {}
	Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
	//重载后置++ 普通全局函数为operator++(a,int)
    //成员函数
	Person operator++(int)
	{
		//先保存 旧的值
		Person old = *this;//*this == lucy
		//lucy++自增
		this-> num = this-> num + 1;
		this-> name = this-> name + this-> name;//(自定义操作)
		this-> score = this-> score + 1;
		return old;//返回旧值
	}
};
ostream& operator<<(ostream& out, Person ob)
{
	out << ob.num << " " << ob.name << " " << ob.score << endl;
	return out;
}
istream& operator>>(istream &in, Person &ob)
{
	in >> ob.num >> ob.name >> ob.score;
	return in;
}	
int main(int argc, char* argv[])
{
	Person lucy(100, "lucy", 85.5f);
	Person bob;
	//先使用 后++
	bob = lucy++;
	cout << bob << endl;
	cout << lucy << endl;
	return 0;
}

(2)重载前置++

#include<iostream>
#include<string>
using namespace std;
class Person
{
	friend ostream& operator<<(ostream& out, Person ob);
	friend istream& operator>>(istream &in, Person &ob);
private:
	int num;
	string name;
	float score;
public:
	Person() {}
	Person(int num, string name, float score) :num(num), name(name), score(score) {}//初始化列表
	//重载后置++ 普通全局函数为operator++(a,int)
    //成员函数
	Person operator++(int)
	{
		//先保存 旧的值
		Person old = *this;//*this == lucy
		//lucy++自增
		this-> num = this-> num + 1;
		this-> name = this-> name + this-> name;//(自定义操作)
		this-> score = this-> score + 1;
		return old;//返回旧值
	}
	//重载前置++ 普通全局函数为operator++(a)
    //成员函数
	Person operator++(int)
	{
		//先++
		this-> num = this-> num + 1;
		this-> name = this-> name + this-> name;//(自定义操作)
		this-> score = this-> score + 1;
        //后使用
		return  *this;
	}
};
ostream& operator<<(ostream& out, Person ob)
{
	out << ob.num << " " << ob.name << " " << ob.score << endl;
	return out;
}
istream& operator>>(istream &in, Person &ob)
{
	in >> ob.num >> ob.name >> ob.score;
	return in;
}	
int main(int argc, char* argv[])
{
	Person lucy(100, "lucy", 85.5f);
	Person bob;
	///先++ 后使用
	bob = ++lucy;
	cout << bob << endl;
	cout << lucy << endl;
	return 0;
}

8、重载函数调用运算符()

        重载()运算符 一般用于 为算法 提供策略。

二、string类

        string类完成重载输入输出、重载中括号运算符、重载+运算符、重载=赋值运算符(深拷贝)、重载>运算符等运算

mystring.h

#ifndef MYSTRING_H
#define MYSTRING_H
#include <iostream>
using namespace std;
class MyString
{
    friend ostream& operator<<(ostream &out, MyString ob);
    friend istream& operator>>(istream &in, MyString &ob);
private:
    char *str;
    int size;
public:
    MyString();
    MyString(char *str);
    MyString(const MyString &ob);//构造拷贝
    ~MyString();
    int getSize() const;
    //成员函数重载[]
    char& operator[](int pos);
    MyString operator+(MyString ob);
    MyString operator+(char *str);

    MyString& operator=(MyString ob);
    MyString& operator=(char *str);

    bool operator>(MyString ob);
    bool operator>(char *str);

    // bool operator<(MyString ob);
    // bool operator<(char *str);
    // bool operator==(MyString ob);
    // bool operator==(char *str);
    // bool operator!=(MyString ob);
    // bool operator!=(char *str);
};

#endif // MYSTRING_H

mystring.cpp

#include "mystring.h"
#include <string.h>

int MyString::getSize() const
{
    return size;
}

char& MyString::operator[](int pos)
{
    if(pos<0 || pos>=size)
    {
        cout<<"元素位置不合法"<<endl;
        exit(‐1);
    }
    return str[pos];
}

MyString MyString::operator+(MyString ob)
{
    MyString tmp;
    tmp.size = size+ob.size;
    tmp.str = new char[tmp.size+1];
    memset(tmp.str, 0, tmp.size+1);

    strcpy(tmp.str, str);
    strcat(tmp.str, ob.str);

    return tmp;
}

MyString MyString::operator+(char *str)
{
    MyString tmp;
    tmp.size = size+strlen(str);
    tmp.str = new char[tmp.size+1];
    memset(tmp.str, 0, tmp.size+1);

    strcpy(tmp.str, this‐>str);
    strcat(tmp.str, str);

    return tmp;
}

MyString &MyString::operator=(MyString ob)
{
    //str2 = str1;
    if(this‐>str != NULL)
    {
        delete [] this‐>str;
        this‐>str = NULL;
    }
    this‐>size = ob.size;
    this‐>str = new char[this‐>size+1];
    memset(this‐>str, 0, this‐>size+1);
    strcpy(this‐>str, ob.str);

    return *this;
}

MyString &MyString::operator=(char *str)
{
    //str2 = str1;
    if(this‐>str != NULL)
    {
    delete [] this‐>str;
    this‐>str = NULL;
    }

    this‐>size = strlen(str);
    this‐>str = new char[this‐>size+1];
    memset(this‐>str, 0, this‐>size+1);
    strcpy(this‐>str, str);
    
    return *this;
}

bool MyString::operator>(MyString ob)
{
    if(str==NULL || ob.str == NULL)
    {
        exit(‐1);
    }
    if(strcmp(this‐>str, ob.str) > 0)
    {
        return true;
    }
        return false;
    }

bool MyString::operator>(char *str)
{
    if(this‐>str==NULL || str == NULL)
    {
        exit(‐1);
    }
    if(strcmp(this‐>str, str) > 0)
    {
        return true;
    }
    return false;
}

MyString::MyString()
{
    str=NULL;
    size=0;
}

myString::MyString(char *str)
{
    size = strlen(str);
    this‐>str = new char[size+1];
    memset(this‐>str, 0, size+1);
    
    strcpy(this‐>str, str);
}

MyString::MyString(const MyString &ob)
{
    size = ob.size;
    str = new char[size+1];
    memset(str, 0, size+1);
    strcpy(str, ob.str);
}

myString::~MyString()
{
    if(str != NULL)
    {
        delete [] str;
        str=NULL;
    }
}

//全局函数实现 <<重载
ostream& operator<<(ostream &out, MyString ob)
{
    out<<ob.str;
    return out;
}
//全局函数实现 >>重载
istream& operator>>(istream &in, MyString &ob)
{
    char buf[1024]="";
    cin>>buf;

    if(ob.str != NULL)//ob已经有字符串
    {
        delete [] ob.str;
        ob.str = NULL;
    }

    ob.size = strlen(buf);
    ob.str = new char[ob.size+1];
    memset(ob.str, 0,ob.size+1);
    strcpy(ob.str, buf);

    return in;
}

三、智能指针

        智能指针:通过重载* 和->运算符。解决 堆区空间的对象 释放问题

class Data
{
public:
    Data()
    {
        cout<<"无参构造"<<endl;
    }
    ~Data()
    {
        cout<<"析构函数"<<endl;
    }
    void func()
    {
        cout<<"func函数"<<endl;
    }
};
class SmartPointer//智能指针类
{
private:
    Data *p;
public:
    SmartPointer(){}
    SmartPointer(Data *p)
    {
    this‐>p = p;
    }
    ~SmartPointer()
    {
        delete p;
    }
    //重载*和->
    Data& operator*()
    {
        return *p;
    }
    Data* operator‐>()
    {
        return p;
    }
};

void test02()
{
    SmartPointer ob(new Data);
    (*ob).func();//ob.operator *().func();

    ob‐>func();//ob.operator ‐>()‐>func();
} 

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

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

相关文章

如何高效地给视频批量添加logo水印?

如果你想给大量的视频添加图片水印&#xff0c;那么固乔剪辑助手软件是一个非常不错的选择。通过这个软件&#xff0c;你可以轻松地批量添加图片水印&#xff0c;提高视频的质量和识别度。以下是如何使用固乔剪辑助手软件给视频批量添加图片水印的步骤&#xff1a; 步骤1&#…

Qt+树莓派4B 窗口半透明效果实现

文章目录 前言一、窗口半透明&#xff0c;窗口部件不透明1、构造函数中的设置2、paintEvent3、效果4、树莓派4B配置5、最终效果 前言 在树莓派4B下&#xff0c;使用Qt开发窗口半透明而窗口部件不透明效果时,发现窗口没能正常实现半透明效果,而是显示纯黑色背景。同样的代码在wi…

PLC 学习day03 PLC软件安装 PLC软件的介绍和对应的知识

1.资料来源 链接&#xff1a;7.PLC编程学习入门视频教程全集-三菱GX-Works2编程软件安装_哔哩哔哩_bilibili 链接&#xff1a;8.三菱plc视频教程全集之编程语言及软元件介绍_哔哩哔哩_bilibili 2. PLC软件的安装 三菱的PLC软件安装视屏的链接&#xff1a; 7.PLC编程学习入门视频…

Gymnasium的基本用法

目录 1.初始化环境 2.与环境交互 3.动作和观测空间 4.修改环境 Gymnasium是一个为所有单智能体强化学习环境提供API的项目&#xff0c;包括常见环境的实现:cartpole、pendulum、mountain-car、mujoco、atari等。 该API包含四个关键功能:make、reset、step和render&#xf…

对称加密操作

#常用密码技术 ##1 密码 1.1 发送者、接收者和窃听者 请想象一个Alice向Bob发送电子邮件的场景。在这个场景中&#xff0c;发出邮件的Alice称为 发送者&#xff08;sender&#xff09;&#xff0c;而收到邮件的Bob则称为 接收者&#xff08;receiver&#xff09;。 在讲解发送…

公司只有功能测试,如何进一步提升自己?

一定要帮助想上进却又迷茫的人。 最近也听到一些做功能测试的同学的交流&#xff0c;天天做手工测试&#xff0c;想提升一下自己又不知道如何提升&#xff1f;其实还是在于这些同学对自己没有一个清晰的定位&#xff0c;没有明确的目标。做为功能测试人员来讲&#xff0c;从发…

【OpenVINO】基于 OpenVINO Python API 部署 RT-DETR 模型

基于 OpenVINO Python API 部署 RT-DETR 模型 1. RT-DETR2. OpenVINO3. 环境配置3.1 模型下载环境3.2 模型部署环境 4. 模型下载与转换4.1 PaddlePaddle模型下载4.2 IR模型转换 5. Python代码实现5.1 模型推理流程实现 6. 预测结果展示7. 总结 RT-DETR是在DETR模型基础上进行改…

JS中面向对象的程序设计

面向对象&#xff08;Object-Oriented&#xff0c;OO&#xff09;的语言有一个标志&#xff0c;那就是它们都有类的概念&#xff0c;而通过类可以创建任意多个具有相同属性和方法的对象。但在ECMAScript 中没有类的概念&#xff0c;因此它的对象也与基于类的语言中的对象有所不…

异常数据检测 | Python基于奇异谱分析时间序列插补预测

文章概述 在时间序列分析中,「奇异谱分析」(「SSA」)是一种非参数谱估计方法。它结合了经典时间序列分析、多元统计、多元几何、动力系统和信号处理的元素。 “奇异谱分析”这个名称涉及协方差矩阵的奇异值分解中的特征值谱,而不是直接涉及频域分解。 SSA 可以帮助分解时…

基于多元宇宙算法的无人机航迹规划-附代码

基于多元宇宙算法的无人机航迹规划 文章目录 基于多元宇宙算法的无人机航迹规划1.多元宇宙搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用多元宇宙算法来优化无人机航迹规划。 …

宝诗单证使用手册,并使用抽象和反射做通用抽象类,节省开发成本

单证示例 1024最适合写blog了&#xff0c;别说了&#xff0c;别说了&#xff0c;建议变成法定节假日。 宝诗单证的官网&#xff1a;宝诗官网 (宝诗团队记得给我打广告费) 宝诗单证的使用步骤 使用 抽象类 将获取字段的步骤抽象出来&#xff0c;极大的省略了代码量。节省开发…

苏州德创机器视觉工程师工作怎么样?

每一家公司都有自身特点&#xff0c;同时也每一家都有自身的bug。 苏州德创作为美国康耐视Cognex产品在华东最大的代理商&#xff0c;也是康耐视外包团队。那么苏州德创有哪些业务构成&#xff0c;业务的构成也是其招聘的主要人员的方向。 设备视觉供应商&#xff0c;如卓越&…

【Linux进阶之路】进程(中)—— 进程地址空间

文章目录 一、 进程地址空间1.概念引入2.基本概念3.深入概念3.1 初识信息交互3.2 区域划分3.3 进程地址空间3.4 再识页表缺页中断进程挂起 总结 一、 进程地址空间 1.概念引入 指针指向的地址是内存中的地址吗&#xff1f;下面我们用一个实验来证明一下。 先来写程序看一下程…

2010-2021年北大中国商业银行数字化转型指数数据(第三期)

2010-2021年北大中国商业银行数字化转型指数数据&#xff08;第三期&#xff09; 1、时间&#xff1a;2010-2021年 2、指标&#xff1a;银行名称、银行类型、年份、战略数字化、业务数字化、管理数字化、数字化总指数 3、来源&#xff1a;北大数字金融研究中心 4、数据说明…

中文大语言和多模态模型测评

Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.A new tool that blends your everyday work apps into one. Its the all-in-one workspace for you and your teamhttps://yaofu.notion.site/C-Eval-6b79edd91b454e3d8ea41c59ea2af873排行榜…

Appium移动端自动测试框架,如何入门?

Appium是一个开源跨平台移动应用自动化测试框架。 既然只是想学习下Appium如何入门&#xff0c;那么我们就直奔主题。文章结构如下&#xff1a; 1、为什么要使用Appium&#xff1f; 2、如何搭建Appium工具环境?(超详细&#xff09; 3、通过demo演示Appium的使用 4、Appium如何…

【Unity程序技巧】异步保险箱管理器

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

Servlet的两种部署方法

Servlet是实现动态页面的技术&#xff0c;是tomcat给Java提供的原生的进行web开发的api 第一个Servlet程序 写一个servlet程序&#xff0c;部署到tomcat上&#xff0c;通过浏览器访问&#xff0c;得到hello world字符串 1.创建项目 此处要创建的是maven项目 maven&#xf…

重磅官宣 | 第二届 OpenHarmony 技术峰会,邀您共启智联未来

"下一个技术未来在哪里&#xff1f;" 11 月 4 日 技术大咖齐聚北京为你解答 一场主论坛八大开源领域分论坛 探究终端操作系统十大技术挑战方向 与全球开源操作系统技术领袖、实践专家、一线导师携手 共绘 OpenHarmony 开源生态璀璨星图&#xff01; 点击链接&…

解决:无法打开Zotero数据库

在实验室电脑上面下载了Zotero和坚果云&#xff0c;一系列操作下来&#xff0c;我的笔记本上无法打开Zotero数据库了&#xff01;显示下面的界面&#xff1a; 于是网上找解决方法 1.https://www.zhihu.com/question/519740718 2.https://devpress.csdn.net/awstech/64e7311b…