当前位置: 首页 > news >正文

2.5 动态字符串 String (完整源码)

C++自学精简教程 目录(必读)

C++数据结构与算法实现(目录)

本文的实现基本上和 动态数组 vector 是一样的。

因为大部分接口都一样。

所以,本文就直接给出全部的源码和运行结果。

//------下面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------
#include <algorithm>
#include <cstdlib>
#include <iostream> 
#include <vector>
#include <utility>
using namespace std;
struct Record { Record(void* ptr1, size_t count1, const char* location1, int line1, bool is) :ptr(ptr1), count(count1), line(line1), is_array(is) { int i = 0; while ((location[i] = location1[i]) && i < 100) { ++i; } }void* ptr; size_t count; char location[100] = { 0 }; int line; bool is_array = false; bool not_use_right_delete = false; }; bool operator==(const Record& lhs, const Record& rhs) { return lhs.ptr == rhs.ptr; }std::vector<Record> myAllocStatistic; void* newFunctionImpl(std::size_t sz, char const* file, int line, bool is) { void* ptr = std::malloc(sz); myAllocStatistic.push_back({ ptr,sz, file, line , is }); return ptr; }void* operator new(std::size_t sz, char const* file, int line) { return newFunctionImpl(sz, file, line, false); }void* operator new [](std::size_t sz, char const* file, int line)
{return newFunctionImpl(sz, file, line, true);
}void operator delete(void* ptr) noexcept { Record item{ ptr, 0, "", 0, false }; auto itr = std::find(myAllocStatistic.begin(), myAllocStatistic.end(), item); if (itr != myAllocStatistic.end()) { auto ind = std::distance(myAllocStatistic.begin(), itr); myAllocStatistic[ind].ptr = nullptr; if (itr->is_array) { myAllocStatistic[ind].not_use_right_delete = true; } else { myAllocStatistic[ind].count = 0; }std::free(ptr); } }void operator delete[](void* ptr) noexcept { Record item{ ptr, 0, "", 0, true }; auto itr = std::find(myAllocStatistic.begin(), myAllocStatistic.end(), item); if (itr != myAllocStatistic.end()) { auto ind = std::distance(myAllocStatistic.begin(), itr); myAllocStatistic[ind].ptr = nullptr; if (!itr->is_array) { myAllocStatistic[ind].not_use_right_delete = true; } else { myAllocStatistic[ind].count = 0; }std::free(ptr); } }
#define new new(__FILE__, __LINE__)
struct MyStruct { void ReportMemoryLeak() { std::cout << "Memory leak report: " << std::endl; bool leak = false; for (auto& i : myAllocStatistic) { if (i.count != 0) { leak = true; std::cout << "leak count " << i.count << " Byte" << ", file " << i.location << ", line " << i.line; if (i.not_use_right_delete) { cout << ", not use right delete. "; }	cout << std::endl; } }if (!leak) { cout << "No memory leak." << endl; } }~MyStruct() { ReportMemoryLeak(); } }; static MyStruct my;
//------上面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------//------check用来检查有没有bug begin------
#include <iostream> 
using namespace std;
void check_do(bool b, int line = __LINE__) { if (b) { cout << "line:" << line << " Pass" << endl; } else { cout << "line:" << line << " Ohh! not passed!!!!!!!!!!!!!!!!!!!!!!!!!!!" << " " << endl; exit(0); } }
#define check(msg)  check_do(msg, __LINE__);
//------check用来检查有没有bug end------class String
{friend std::ostream& operator<<(std::ostream& os, const String& str);
public:String(void);String(const char* data, int length);String(const char* data);String(const String& from);//1 复制构造String& operator = (const String& from);//2 赋值操作符size_t size(void) const { return m_length; }bool empty(void) const { return m_length == 0; }~String();//3 析构函数bool operator == (const String& other);bool operator != (const String& other) { return !(*this == other); }String operator+(const String& other);void push_back(char c);void clear(void);protected:void copy(const char* data, size_t length);
private:char* m_data;size_t m_length;int m_capacity = 0;
};
void String::push_back(char c)
{if (m_capacity > m_length)//直接追加到最后一个{m_data[m_length++] = c;}else//只有满了的那一瞬间,才翻倍开辟新空间{m_capacity = (m_capacity == 0 ? 10 : m_capacity + m_capacity);auto pNewArray = new char[m_capacity];//拷贝老数据for (size_t i = 0; i < m_length; i++){pNewArray[i] = m_data[i];}//追加最新的末尾元素pNewArray[m_length++] = c;delete[] m_data;m_data = pNewArray;}
}
std::ostream& operator<<(std::ostream& os, const String& str)
{for (size_t i = 0; i < str.m_length; ++i){os << str.m_data[i];}return os;
}
String::String(void) :m_data(nullptr), m_length(0)
{
}
String::~String()
{clear();
}
bool String::operator==(const String& other)
{if (other.m_length != this->m_length){return false;}for (size_t i = 0; i < m_length; i++){auto c1 = m_data[i];auto c2 = other.m_data[i];if (c1 != c2){return false;}}return true;
}
String String::operator+(const String& other)
{if (other.empty()){return *this;}String result;result.m_length = m_length + other.m_length;result.m_data = new char[result.m_length];for (size_t i = 0; i < m_length; i++){result.m_data[i] = m_data[i];}for (size_t i = 0; i < other.m_length; i++){result.m_data[m_length + i] = other.m_data[i];}return result;
}
String::String(const char* data, int _length) :m_data(nullptr), m_length(0)
{copy(data, _length);
}
String::String(const char* data) : m_data(nullptr), m_length(0)
{int stringLength = 0;auto p = data;while (*p != '\0'){++stringLength;++p;}copy(data, stringLength);
}
String::String(const String& from) : m_data(nullptr), m_length(0)
{if (from.m_data != m_data){copy(from.m_data, from.m_length);}
}
String& String::operator=(const String& from)
{if (&from != this){copy(from.m_data, from.m_length);}return *this;
}void String::clear(void)
{if (nullptr != m_data){delete[] m_data;m_data = nullptr;m_length = 0;}
}
void String::copy(const char* data, size_t length)
{clear();m_data = new char[length];for (size_t i = 0; i < length; ++i){m_data[i] = data[i];}m_length = length;
}String GetLeftValue(void)
{String s("String");return s;
}
void Test0(void)
{auto leftValue1 = GetLeftValue();String left2;left2 = (left2 = leftValue1);std::vector<String> arrStr(2);left2 = (arrStr[0]);String arr[2];left2 = (arr[0]);auto p = arr;left2 = (*p);arrStr.push_back(left2);
}
void Test_empty(void)
{String s("");check(s.empty());check(s.size() == 0);check(s == "");
}
void Test_clear(void)
{String s2;{String s("123");check(s == "123");s2 = s;s.clear();s.clear();check(s.size() == 0);check(s.empty());check(s == "");check(s2 != s);}check(s2 == "123");
}
void Test_copy(void)
{{String s1("Hello World!");//constructorString s2(s1);//copy constructorcout << s2 << endl;//operator<<check(s1.size() == s2.size());//sizeString s3;s3 = s2;check(s3 == s1);check(!s3.empty());check(!s1.empty());s1 = s2 = s2 = s1;check(s1.size() == s2.size());//sizecheck(s3 == s1);check(!s3.empty());check(!s1.empty());check(s1 == "Hello World!");s1.clear();check(s1.empty());check(s1 != s2);check(s2 == s3);}{String s;check(s.empty());}// +{String s1("Hello World!");//constructorString s2("Hello World!");//constructorString s3(s1 + s2);check(s3.size() == s1.size() + s2.size());check(s3 == s1 + s2);check(s3 == "Hello World!Hello World!");}{const char* p = "Hello World !";String s(p);check(s == p);}//push_back{String s;check(s.size() == 0);check(s.empty());s.push_back('a');check(s == "a");for (size_t i = 0; i < 100; i++){s.push_back('a');}check(s.size() == 101);}
}String GetValue(void)
{String a;String b;b = a;return a;
}int main()
{Test0();Test_empty();Test_copy();Test_clear();return 0;
}

正确的运行结果:

line:194 Pass
line:195 Pass
line:196 Pass
Hello World!
line:220 Pass
line:223 Pass
line:224 Pass
line:225 Pass
line:227 Pass
line:228 Pass
line:229 Pass
line:230 Pass
line:231 Pass
line:233 Pass
line:234 Pass
line:235 Pass
line:239 Pass
line:246 Pass
line:247 Pass
line:248 Pass
line:253 Pass
line:258 Pass
line:259 Pass
line:261 Pass
line:266 Pass
line:203 Pass
line:207 Pass
line:208 Pass
line:209 Pass
line:210 Pass
line:212 Pass
Memory leak report:
No memory leak.

欢迎参考借鉴,如有问题欢迎评论指出!

祝你好运!

相关文章:

2.5 动态字符串 String (完整源码)

C自学精简教程 目录(必读) C数据结构与算法实现&#xff08;目录&#xff09; 本文的实现基本上和 动态数组 vector 是一样的。 因为大部分接口都一样。 所以&#xff0c;本文就直接给出全部的源码和运行结果。 //------下面的代码是用来测试你的代码有没有问题的辅助代码…...

Ansible之变量

一&#xff09;Ansible变量介绍 我们在PlayBook⼀节中&#xff0c;将PlayBook类⽐成了Linux中的shell。 那么它作为⼀⻔Ansible特殊的语⾔&#xff0c;肯定要涉及到变量定义、控 制结构的使⽤等特性。 在这⼀节中主要讨论变量的定义和使⽤ 二&#xff09;变量命名规则 变量的…...

自动化测试面试常见技术题目

1&#xff1a;一行代码实现1--100之和 print(sum(list(range(1,101)))) 2&#xff1a;如何在一个函数内部修改全局变量 global  修改全局变量 局部作用域只能调用全局作用域的变量&#xff0c;但是不熊修改全局作用域的变量&#xff0c;如果想要修改全局作用域的变量需要gl…...

aarch64 arm64 部署 stable diffusion webui 笔记 【2】继续安装其他依赖 gfpgan

接上篇 aarch64 arm64 部署 stable diffusion webui 笔记 【1】准备 venv 安装pytorch 验证cuda_hkNaruto的博客-CSDN博客 编辑requirements_versions.txt&#xff0c;注释掉torch 启动webui.sh (venv) [rootceph3 stable-diffusion-webui]# useradd yeqiang useradd&#xf…...

使用ECS和RDS部署WordPress,搭建个人博客并使用域名访问

目录 一、准备工作 1、准备ECS服务器 2、创建数据库账号和密码 二、部署环境 1、远程连接 2、安装Apache服务 3、部署WordPress 三、对博客的优化并使用域名访问 1、博客的设计优化 1.1 插件的使用 1.2 博客的设计介绍 2、使用域名访问 四、个人博客部署的心得 1…...

C# Winform 简单排期实现(DevExpress TreeList)

排期的需求在很多任务安排的系统中都有相应的需求&#xff0c;原生的Winform控件并未提供相应的控件&#xff0c;一般都是利用DataGridViewTreeView组合完成相应的需求&#xff0c;实现起来比较麻烦。用过DevExpress控件集的开发者应该知道&#xff0c;DevExpress WinForm提供了…...

2023高教社杯国赛数学建模C题思路+模型+代码(9.7晚开赛后第一时间更新)

目录 1.C题思路模型&#xff1a;9.7晚上比赛开始后&#xff0c;第一时间更新&#xff0c;获取见文末名片 2.竞赛注意事项&#xff1a;包括比赛流程&#xff0c;任务分配&#xff0c;时间把控&#xff0c;论文润色&#xff0c;已经发布在文末名片中 3.常用国赛数学建模算法 …...

QT6中添加串口模块SerialPort最简单方法

qt6.2.3以上版本已经开始支持SerialPort包了&#xff0c;不用在傻傻的自己去编译包了。 在安装的时候勾选SerialPort即可。 等着安装完即可。 如果已经安装完了的小伙伴&#xff0c;可以用 从新打开维护 选择增加或者删除组件 即可从新选择组件...

LeetCode每日一题:1123. 最深叶节点的最近公共祖先(2023.9.6 C++)

目录 1123. 最深叶节点的最近公共祖先 题目描述&#xff1a; 实现代码与解析&#xff1a; dfs 原理思路&#xff1a; 1123. 最深叶节点的最近公共祖先 题目描述&#xff1a; 给你一个有根节点 root 的二叉树&#xff0c;返回它 最深的叶节点的最近公共祖先 。 回想一下&…...

Oracle查看锁表和正在执行的Sql

查看当前被锁的表&#xff08;需要有管理员权限&#xff09;&#xff1a; --查看锁表进程SQL语句1&#xff1a; select sess.sid,sess.serial#,lo.oracle_username,lo.os_user_name,ao.object_name,lo.locked_modefrom v$locked_object lo, dba_objects ao, v$session sesswh…...

Linux centos 卸载 ceph

在CentOS上卸载Ceph的操作步骤&#xff1a; 1. 停止Ceph集群&#xff1a;首先&#xff0c;你需要停止Ceph集群中的所有服务。在每个节点上运行以下命令来停止所有服务 systemctl stop ceph.target 2. 卸载Ceph软件包&#xff1a;在每个节点上&#xff0c;使用yum包管理器卸载C…...

ElementUI浅尝辄止34:Radio 单选框

在一组备选项中进行单选 1.如何使用&#xff1f; 由于选项默认可见&#xff0c;不宜过多&#xff0c;若选项过多&#xff0c;建议使用 Select 选择器。 //要使用 Radio 组件&#xff0c;只需要设置v-model绑定变量&#xff0c;选中意味着变量的值为相应 Radio label属性的值&…...

开始MySQL之路——MySQL三大日志(binlog、redo log和undo log)概述详解

前言 MySQL实现事务、崩溃恢复、集群的主从复制&#xff0c;底层都离不开日志&#xff0c;所以日志是MySQL的精华所在。只有了解MySQL日志&#xff0c;才算是彻底搞懂MySQL。 日志是mysql数据库的重要组成部分&#xff0c;记录着数据库运行期间各种状态信息。mysql日志主要包…...

router基础使用

1.安装router npm i vue-router3 安装后 2.写出路由界面 接着 3.配置路由 import Vue from vue import VueRouter from vue-router import Home from "../views/Home.vue" import About from "../views/About.vue" Vue.use(VueRouter)const routes …...

亚马逊云科技人工智能内容审核服务:大大降低生成不安全内容的风险

生成式人工智能技术发展日新月异&#xff0c;现在已经能够根据文本输入生成文本和图像。Stable Diffusion是一种文本转图像模型&#xff0c;可以创建栩栩如生的图像应用。通过Amazon SageMaker JumpStart&#xff0c;使用Stable Diffusion模型轻松地从文本生成图像。 尽管生成式…...

2023年高教社杯数学建模思路 - 案例:最短时间生产计划安排

文章目录 0 赛题思路1 模型描述2 实例2.1 问题描述2.2 数学模型2.2.1 模型流程2.2.2 符号约定2.2.3 求解模型 2.3 相关代码2.4 模型求解结果 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 最短时…...

算法工程题(二叉树递归)

* 题意说明&#xff1a; * 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 * 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 * * 示例 1&#xff1a; * 输入&#xff1a;p [1,2,3]…...

“指针跃动”受邀参加全球贸易服务峰会

“指针跃动”受邀参加全球贸易服务峰会 有“服”同享 共赢未来 引子 在全球化日益盛行的今天&#xff0c;贸易不再仅仅是物质的交流&#xff0c;更涉及到服务、理念、文化和科技的共享。中国国际服务贸易交易会全球贸易服务峰会&#xff0c;就是这个趋势的集中体现。在这次峰会…...

Go Web开发的高级技巧和最佳实践

Go Web开发的高级技巧和最佳实践 欢迎来到Go语言Web开发的高级技巧和最佳实践指南。在这篇文章中&#xff0c;我们将深入探讨Go语言Web应用程序的高级主题&#xff0c;包括性能优化、安全性、部署和微服务架构。 性能优化 性能是Web应用程序的关键因素之一。Go语言以其出色的…...

Verilog 基础知识

1、数值种类 Verilog HDL 有下列四种基本的值来表示硬件电路中的电平逻辑&#xff1a; 0&#xff1a;逻辑 0 或 “假”1&#xff1a;逻辑 1 或 “真”x 或 X&#xff1a;未知 x 意味着信号数值的不确定&#xff0c;即在实际电路里&#xff0c;信号可能为 1&#xff0c;也可能…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...