C++中实现String类

String类实现

  • 概述
  • 示例
    • 开发环境
    • 代码
    • 运行结果
  • 注意

概述

本文主要记录自己实现一个String类中的部分功能。

示例

开发环境

Windows下Visual Studio 2019。

代码

MyString.h

#pragma once
#include <iostream>class MyString{
public:MyString();MyString(char *p);MyString(const char *p);MyString(const MyString& s);MyString(MyString&& s);MyString& operator=(const MyString& s);MyString& operator=(MyString&& s);bool operator<(const MyString &s);bool operator==(const MyString& s);MyString& operator+=(const MyString& s);int getLeng()const;char getIndexCharacter(const int& index);friend std::ostream& operator<<(std::ostream & o,const MyString& s);//友元函数不是类成员函数,可访问私有成员friend std::istream& operator>>(std::istream& i,MyString &s);
private:char* m_pStr;int m_len;
};

MyString.cpp

#include "MyString.h"
#include <string>MyString::MyString():m_pStr(nullptr),m_len(0)
{m_pStr = new char[1];m_pStr[0] = '\0';m_len = 1;
}MyString::MyString(char* p)
{if (p) {int nLen = strlen(p);m_pStr = new char[nLen + 1];memset(m_pStr, 0, nLen + 1);strcpy_s(m_pStr, nLen + 1, p);//目标缓存区的大小m_len = nLen;}else {MyString();}
}MyString::MyString(const char* p)
{if(p){int nLen = strlen(p);m_pStr = new char[nLen +1];memset(m_pStr,0,nLen+1);strcpy_s(m_pStr,nLen+1,p);//目标缓存区的大小m_len = nLen;}else {MyString();}
}MyString::MyString(const MyString& s)
{m_len = s.m_len;m_pStr = new char[m_len+1];memset(m_pStr, 0, m_len + 1);strcpy_s(m_pStr,m_len+1 ,s.m_pStr);m_pStr[m_len] = '\0';
}MyString::MyString(MyString&& s)
{m_len = s.m_len;m_pStr = s.m_pStr;s.m_pStr = nullptr;s.m_len = 0;
}MyString& MyString::operator=(const MyString& s)
{// TODO: 在此处插入 return 语句if (this != &s) {m_len = s.m_len;m_pStr = new char[m_len +1];memset(m_pStr,0,m_len+1);strcpy_s(m_pStr,m_len+1,s.m_pStr);m_pStr[m_len] = '\0';}return *this;
}MyString& MyString::operator=(MyString&& s)
{// TODO: 在此处插入 return 语句if (this != &s) {m_len = s.m_len;m_pStr = s.m_pStr;s.m_len = 0;s.m_pStr = nullptr;}return *this;
}bool MyString::operator<(const MyString& s)
{if (strcmp(m_pStr,s.m_pStr) < 0) {return true;}return false;
}bool MyString::operator==(const MyString& s)
{if (strcmp(m_pStr,s.m_pStr) == 0) {return true;}return false;
}MyString& MyString::operator+=(const MyString& s)
{// TODO: 在此处插入 return 语句m_len += s.m_len;char* pTemp = m_pStr;m_pStr = new char[m_len+1];memset(m_pStr,0,m_len+1);strcpy_s(m_pStr,m_len+1,pTemp);strcat_s(m_pStr, m_len + 1, s.m_pStr);m_pStr[m_len] = '\0';return *this;
}int MyString::getLeng() const
{return m_len;
}char MyString::getIndexCharacter(const int& index)
{if (index >=0 && index < m_len) {return m_pStr[index];}return -1;
}std::ostream& operator<<(std::ostream& o,const MyString& s)
{// TODO: 在此处插入 return 语句o << "字符串的长度:" << s.m_len << ",字符串:" << s.m_pStr;return o;
}std::istream& operator>>(std::istream& i,MyString &s)
{// TODO: 在此处插入 return 语句i >> s.m_len >> s.m_pStr;return i;
}

main.cpp

#include <iostream>
#include "MyString.h"using namespace std;int main(int argc,char *argv[]) {MyString s;cout <<"字符串s: "<< s << endl;const char* p = "future";MyString s0(p);cout << "字符串s0: " << s0 << endl;MyString s1("hello");cout << "字符串s1: " << s1 << endl;char c[15] = "hello world";MyString s2(c);cout << "字符串S2:" << s2 << endl;MyString s3(s2);cout << "字符串s3:" << s3 << endl;MyString s4(move(s0));cout << "字符串s4:" << s4 << endl;MyString s5 = s1;cout << "字符串s5:" << s5 << endl;MyString s6 = move(s2);cout << "字符串s6:" << s6 << endl;if (s5 == s6) {cout << "s5与s6相等!" << endl;}else if(s5 <s6){cout << "s5与s6小于s6!" << endl;}else {cout << "s5与s6大于s6!" << endl;}s5 += s6;cout << "s5追加s6之后: " << s5 << endl;cout << "s5的长度:" <<s5.getLeng()<< endl;cout << "s5的第8个字符:" << s5.getIndexCharacter(11) << endl;return 0;
}

运行结果

在这里插入图片描述

注意

  • 上面的示例在实现时,输入输出运算符的重载时作为友元函数来声明的,需要访问类对象的成员变量,故而含有两个参数。
    一般输出、输出运算符重载都作为类的友元函数。
friend std::ostream& operator<<(std::ostream & o,const MyString& s);//友元函数不是类成员函数,可访问私有成员
friend std::istream& operator>>(std::istream& i,MyString &s);
  • 其中构造函数:
MyString(MyString&& s);

为移动拷贝构造函数。

  • 下面的赋值运算符重载:
MyString& operator=(MyString&& s);

为移动赋值运算符重载。
参数右值引用传参的时候,使用move()。 可看上述示例调用处。

  • 声明为移动构造函数和移动赋值运算符重载的好处 :
    避免了深拷贝,只转移所有权,移动之后(即转移所有权之后),原来的对象中的数据被清空,但对象依旧存在。

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

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

相关文章

github登录时解决2FA问题

使用Edge浏览器下载插件 https://microsoftedge.microsoft.com/addons/detail/authenticator-2fa-client/ocglkepbibnalbgmbachknglpdipeoio 下载后弹框会显示是否添加&#xff0c;添加。如下&#xff1a; Chrome下 https://chrome.google.com/webstore/detail/authenticator…

景联文科技:提供通用多模态数据,助力AI多模态领域实现飞跃式发展

回顾2023年&#xff0c;以ChatGPT为代表的通用人工智能大模型在全球范围内掀起了新一轮人工智能产业发展浪潮&#xff0c;我国人工智能大模型市场呈现百“模”争鸣、日新月异的迅猛发展态势。 根据大模型之家、钛媒体数据&#xff0c;2023年中国大模型市场规模达到147亿人民币&…

Elasticsearch:从 Java High Level Rest Client 切换到新的 Java API Client

作者&#xff1a;David Pilato 我经常在讨论中看到与 Java API 客户端使用相关的问题。 为此&#xff0c;我在 2019 年启动了一个 GitHub 存储库&#xff0c;以提供一些实际有效的代码示例并回答社区提出的问题。 从那时起&#xff0c;高级 Rest 客户端 (High Level Rest Clie…

vizro,一个有趣的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个有趣的 Python 库 - vizro。 Github地址&#xff1a;https://github.com/mckinsey/vizro 在当今数据驱动的世界中&#xff0c;数据可视化扮演着至关重要的角色。它不仅可以…

西门子PLC常用底层逻辑块分享_电动蝶阀

文章目录 前言一、功能概述二、电动蝶阀程序编写1.创建自定义数据类型2.创建FB功能块“电动蝶阀”3.编写程序 前言 本文分享一个自己编写的电动蝶阀控制逻辑块。 一、功能概述 手动状态、自动状态、机旁状态、强制状态、检修状态自由切换&#xff1b;具有开阀超时、关阀超时报…

状态机高阶讲解-06

1069 00:45:36,160 --> 00:45:37,660 那下一个用途 1070 00:45:39,010 --> 00:45:43,830 就是为分割系统提供一些参考的证据了 1071 00:45:47,230 --> 00:45:49,470 现在很多那个 1072 00:45:49,880 --> 00:45:51,770 流行有微服务架构 1073 00:45:51,770 --&g…

MATLAB/SIMULINK流水账

01.模块大小的一致性 当模型建完以后&#xff0c;模型大小比较散乱&#xff0c;可以利用该功能快速整理模块的大小 例如&#xff1a;如下5个constant模块&#xff0c;大小不一 若想把所有的模块都调整至跟第3个模块一样的大小 需要先把5个模块全部选取起来&#xff0c;另外再…

数字多空策略(实盘+回测+数据)

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

3.15号arm

汇编语言 1. 汇编语言的组成 汇编文件中由伪操作、伪指令、汇编指令以及代码注释这几部分组成 伪操作&#xff1a; ARM的汇编中伪操作以.为前缀&#xff0c;所有的伪操作不占用内存空间&#xff0c;编译汇编时告诉编译器怎么编译当前文件&#xff0c;主要用来修改汇编内…

QT下跨平台库实现及移植经验分享

最近在移植公司一个QT桌面软件到android上&#xff0c;有一些公司自定义的库&#xff0c;用了很多windows的api&#xff0c;移植过程很是曲折&#xff0c;在此有一些感悟分享一下~ 一.自编写跨平台库 1.有时候为了程序给第三方用需要编译一些qt封装库&#xff0c;并可能跨平台…

【SQL Server】实验四 数据更新

1 实验目的 掌握SQL数据更新语句的基本使用方法&#xff0c;如UPDATE、DELETE、INSERT。掌握更新语句条件中的嵌套查询使用方法。 2 实验内容 2.1 掌握SQL更新语句的基本使用方法 INSERT基本语句。UPDATE基本语句。DELETE基本语句。 2.2 掌握SQL更新语句的高级使用方法 …

Soft Robotics 变结构手掌和变刚度手指的仿人软体手的人机交互操作-武科大ESIR课题组师兄成果

一、引言 在当今的机器人技术领域&#xff0c;人类对机器人的需求日益增长&#xff0c;涉及到工业生产、医疗护理、服务业等各个领域。然而&#xff0c;由于任务的多样性和复杂性&#xff0c;单独依靠自主机器人操作往往难以满足实际需求。为了解决这一问题&#xff0c;人机协作…

社交革命的引领者:探索Facebook如何改变我们的生活方式

1.数字社交的兴起 随着互联网的普及&#xff0c;社交媒体成为我们日常生活的重要组成部分。Facebook作为其中的先驱&#xff0c;从最初的社交网络演变成了一个拥有数十亿用户的全球化平台。它不仅改变了我们与世界互动的方式&#xff0c;还深刻影响了我们的社交习惯、人际关系以…

从 VNCTF2024 的一道题学习QEMU Escape

说在前面 本文的草稿是边打边学边写出来的&#xff0c;文章思路会与一个“刚打完用户态 pwn 题就去打 QEMU Escape ”的人的思路相似&#xff0c;在分析结束以后我又在部分比较模糊的地方加入了一些补充&#xff0c;因此阅读起来可能会相对轻松。&#xff08;当然也不排除这是…

Python面试笔记

Python面试笔记 PythonQ. Python中可变数据类型与不可变数据类型&#xff0c;浅拷贝与深拷贝详解Q. 解释什么是lambda函数&#xff1f;它有什么好处&#xff1f;Q. 什么是装饰器&#xff1f;Q. 什么是Python的垃圾回收机制&#xff1f;Q. Python内置函数dir的用法&#xff1f;Q…

论文阅读——VSA

VSA: Learning Varied-Size Window Attention in Vision Transformers 方法&#xff1a; 给定输入特征X&#xff0c;VSA首先按照基线方法的例程&#xff0c;将这些标记划分为几个窗口Xw&#xff0c;窗口大小为预定义的w。我们将这些窗口称为默认窗口&#xff0c;并从默认窗口中…

Oracle 一键巡检自动生成 Word 报告

前言 Oracle 数据库巡检通常需要消耗大量时间和精力&#xff0c;包括收集数据库以及主机的相关信息。针对 Word 报告的样式调整&#xff0c;也是重复和费事的&#xff0c;所以我针对 Oracle 巡检所需检查的信息以及报告模板&#xff0c;写了一套自动巡检并且生成报告的脚本。巡…

C++语法、Linux命令查询网站

文章目录 1.cplusplus2.cppreference3.Linux命令查询网站 1.cplusplus 网址&#xff1a;https://legacy.cplusplus.com/ 2.cppreference 1.cppreference中文网站&#xff1a;https://zh.cppreference.com/w/首页 2.cppreference英文原站&#xff1a;https://en.cppreference…

Java获取视频封面图,利用FFmpegFrameGrabber获取视频封面图

依赖 <dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.9</version></dependency>传入视频流获取图片byte /*** 获取视频截图** param frameNumber 视频的指定帧数* param …

Unity AI Navigation插件快速使用方法

AI Navigation插件使您能够创建能够在游戏世界中智能移动的角色。这些角色利用的是根据场景几何结构自动生成的导航网格。障碍物可以让您在运行时改变角色的导航路径。 演示使用的Unity版本为Tuanjie 1.0.0,团结引擎是Unity中国的引擎研发团队基于Unity 2022 LTS版本为中国开发…