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

动态字符串 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.

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

祝你好运!

相关文章:

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

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

【深度学习】实验05 构造神经网络示例

文章目录 构造神经网络1. 导入相关库2. 定义一个层3. 构造数据集4. 定义基本模型5. 变量初始化6. 开始训练 构造神经网络 注明&#xff1a;该代码用来训练一个神经网络&#xff0c;网络拟合y x^2-0.5noise&#xff0c;该神经网络的结构是输入层为一个神经元&#xff0c;隐藏层…...

用了这么久SpringBoot却还不知道的一个小技巧

前言 你可能调第三方接口喜欢启动application&#xff0c;修改&#xff0c;再启动&#xff0c;再修改&#xff0c;顺便还有个不喜欢写JUnitTest的习惯。 你可能有一天想要在SpringBoot启动后&#xff0c;立马想要干一些事情&#xff0c;现在没有可能是你还没遇到。 那么SpringB…...

Websocket、SessionCookie、前端基础知识

目录 1.Websocket Websocket与HTTP的介绍 不同使用场景 Websocket链接过程 2.Session&Cookie Cookie的工作原理 Session的工作原理 区别 3.前端基础知识 1.Websocket Websocket与HTTP的介绍 HTTP&#xff1a; 1.HTTP是单向的&#xff0c;客户端发送请求&#xff0…...

【云原生进阶之PaaS中间件】第一章Redis-2.4缓存更新机制

1 缓存和数据库的数据一致性分析 1.1 Redis 中如何保证缓存和数据库双写时的数据一致性&#xff1f; 无论先操作db还是cache&#xff0c;都会有各自的问题&#xff0c;根本原因是cache和db的更新不是一个原子操作&#xff0c;因此总会有不一致的问题。想要彻底解决这种问题必须…...

Qt——事件处理详解

Qt事件处理 一、事件基础 事件是Qt应用程序中的基本构建块&#xff0c;它们代表了一些特定的行为或状态变化。事件可以是鼠标点击、键盘输入、窗口大小改变、定时器事件等。每个事件都是一个对象&#xff0c;继承自QEvent类。 二、事件常见类型 Qt中的事件分为多种类型&…...

基于位置管理的企业员工考勤打卡系统设计 微信小程序

员工考勤打卡系统设计app是针对员工必不可少的一个部分。在公司发展的整个过程中&#xff0c;员工考勤打卡系统设计app担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类员工考勤打卡系统设计app程序也在不断改进。本课题所设计的 MVC基于HBuilder X的员工考勤…...

adb 查找应用包名,应用 Activity 等信息

列出设备上的包 不使用参数&#xff1a;adb shell pm list packages&#xff0c;打印设备/模拟器上的所有软件包 根据包名查看应用的activity 命令&#xff1a; dumpsys package 包名 adb shell dumpsys package 包名 petrel-cv96d:/data/app # dumpsys package com.instal…...

八、SpringBoot集成Kafka

目录 一、添加依赖二、SpringBoot 生产者三、SpringBoot 消费者 一、添加依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><depend…...

联网智能实时监控静电离子风机的工作流程

联网智能实时监控静电离子风机是通过将静电离子风机与互联网连接&#xff0c;实现对其状态和性能的远程监控和管理。 具体实现该功能的方法可以包括以下几个步骤&#xff1a; 1. 传感器安装&#xff1a;在静电离子风机上安装适当的传感器&#xff0c;用于感知相关的参数&…...

第12章 微信支付

mini商城第12章 微信支付 一、课题 微信支付 二、回顾 1、分布式事务 2、分布式事务理论 3、掌握分布式事务解决方案模型 4、能基于Seata解决强一致性分布式事务 5、能基于RocketMQ解决柔性事务 三、目标 1、密码安全学 摘要加密 Base64 对称加密 2、微信支付 微信支…...

Java基础二十二(对集合元素排序比较)

对集合元素排序比较 1. 使用 Comparable 接口实现默认排序 Comparable 是 Java 中的一个接口&#xff0c;用于定义对象之间的排序规则。 实现了 Comparable 接口的类可以比较其对象的大小&#xff08;包装类都实现了该接口&#xff09;&#xff0c;从而可以在集合类&#xf…...

(15)线程的实例认识:同步,异步,并发,并发回调,事件,异步线程,UI线程

参看&#xff1a;https://www.bilibili.com/video/BV1xA411671D/?spm_id_from333.880.my_history.page.click&vd_source2a0404a7c8f40ef37a32eed32030aa18 下面是net framework版本 一、文件构成 1、界面如下。 (1)同步与异步有什么区别&#xff1f; …...

长胜证券:华为“黑科技”点燃A股炒作激情

8月29日&#xff0c;在未举行相关发布会的情况下&#xff0c;华为新款手机Mate60Pro悄然上线开售&#xff0c;并在一小时内售罄。 金融出资报记者注意到&#xff0c;跟着商场对新机重视的继续发酵&#xff0c;其中的各种技能打破也愈加受到重视&#xff0c;其影响很快扩散到资…...

Kubernetes(k8s)上部署redis5.0.14

Kubernetes上部署redis 环境准备创建命名空间 准备PV和PVC安装nfs准备PV准备PVC 部署redis创建redis的配置文件部署脚本挂载数据目录挂载配置文件通过指定的配置文件启动redis 集群内部访问外部链接Redis 环境准备 首先你需要一个Kubernetes环境&#xff0c;可参考我写的文章&…...

frida动态调试入门01——定位关键代码

说明 frida是一款Python工具可以方便对内存进行hook修改代码逻辑在移动端安全和逆向过程中常用到。 实战 嘟嘟牛登录页面hook 使用到的工具 1&#xff0c;jadx-gui 2&#xff0c;frida 定位关键代码 使用jadx-gui 进行模糊搜索&#xff0c;例如搜索encyrpt之类的加密关键…...

ASP.NET Core 8 的配置类 Configuration

Configuration Configuration 可以从两个途径设置&#xff1a; WebApplication创建的对象app.Configuration 属性WebApplicationBuilder 创建的 builder.Configuration 属性 app的Configuration优先级更高&#xff0c;host Configuration作为替补配置&#xff0c;因为app运行…...

MySql增量恢复

一、 使用二进制日志的时间点恢复 注意 本节和下一节中的许多示例都使用mysql客户端来处理mysqlbinlog生成的二进制日志输出。如果您的二进制日志包含\0&#xff08;null&#xff09;字符&#xff0c;那么mysql将无法解析该输出&#xff0c;除非您使用--binary模式选项调用它。…...

设计模式--装饰者模式(Decorator Pattern)

一、什么是装饰者模式&#xff08;Decorator Pattern&#xff09; 装饰者模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你在不修改现有对象的情况下&#xff0c;动态地将新功能附加到对象上。这种模式通过创建一个包装类&#xff0c;…...

Spring三级缓存解决循环依赖

Spring三级缓存解决循环依赖 一 Spring bean对象的生命周期 二 三级缓存解决循环依赖 实现原理解析 spring利用singletonObjects, earlySingletonObjects, singletonFactories三级缓存去解决的&#xff0c;所说的缓存其实也就是三个Map 先实例化的bean会通过ObjectFactory半…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...