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

日常知识点之面试后反思裸写string类

1:实现一个字符串类。 简单汇总

最简单的方案,使用一个字符串指针,以及实际字符串长度即可。

参考stl的实现,为了提升string的性能,实际上单纯的字符串指针和实际长度是不够了,如上,有优化方案,除此之外,考虑reserve() 以及重置容量,迭代器的相关实现逻辑 (小字符串的存储优化,结合占用内存大小(4的倍数)分配适当的缓冲区更好)。

在这里插入图片描述

类中如果没有成员变量,类的大小为1,如果有成员变量,类的大小即为成员变量的大小。(以前研究过 sizeof(string)的长度 可能是28 或者32)

2:实现注意细节

1:c字符串指针+ 实际字符串的长度进行数据存储

2:内存的申请和释放 用new/delete 或者malloc/free都可以吧, 字符串的赋值借用strcpy 或者memcpy都可以吧。

3:默认构造函数 c字符串传参构造 拷贝构造(深拷贝) 移动构造(浅拷贝 std::move) 赋值复制构造 赋值移动构造(右参std::move)

4:注意整个过程中 const参数的修饰,以及相关函数返回值 返回引用对象和返回对象。

5:重载必要的运算符(+ = == ),输入输出的重载(<< >>),注意重载<<和>>时和friend关键字配合,以及实现细节。

6:c字符串相关函数(strcpy strcmp strlen strcat strchr

在这里插入图片描述

3:源码测试

3.1 类的声明(思考const,noexcept修饰,复制传参,引用传参,以及返回值返回引用 返回对象)

/*************************************
1:不需要考虑太多,直接字符串指针和长度进行实现。
2:考虑该类的大小,如果字符串为null时,如果字符串有长度时。 (字符串拼接  截断等)
3:字符串性能的优化,短字符串直接存栈中,长的进行申请。  其他考虑迭代器等的实现方案。只考虑指针和长度进行实现:1:默认构造函数。2:C字符串初始化,直接初始化,移动构造。   拷贝构造函数,赋值构造函数。3:重载运算符 = == + << >> +=
**************************************/
#include <iostream>
#include <cstring>#include <stdio.h>
class my_string
{
private:char* data;size_t length;public://默认构造函数 c字符串构造  拷贝构造函数 移动构造函数  赋值构造函数 my_string();my_string(const char* str);my_string(const my_string& other);my_string(my_string&& other) noexcept;~my_string();size_t size() const;const char* c_str() const;//=  ==  +  <<my_string& operator = (const my_string& other) noexcept; //赋值构造函数 复制my_string& operator = (my_string&& other) noexcept;  //移动赋值构造函数bool  operator==(const my_string& other) const;my_string operator +(const my_string& other) const;
//注意friend的定义friend std::ostream& operator<<(std::ostream& os, const my_string& str);friend std::istream& operator>>(std::istream& in, my_string& str); //输入需要可修改
};

3.2 类的定义

//函数前面用const 表示的是函数返回值const
//函数后面用用const修饰 可以使常量调用,表示该函数内部不可以修改成员变量 
my_string::my_string() :data(nullptr), length(0)
{printf("my_string() \n");data = new char[1];data[0] = '\0';
}//c字符串对string进行初始化  c字符串为NULL 不为NULL  
//以及c字符串本身也是一以\0终止
my_string::my_string(const char* str)
{printf(" my_string(const char * str) = %s \n", str);if (str){length = strlen(str); //str为NULL  会导致抛异常 data = new char[length + 1];strcpy(data, str);}else{data = new char[1];data[0] = '\0';length = 0;}
}//字符串之间 拷贝构造函数 使用传递引用的方式提升性能 
//在自己类的成员函数中   参数可以直接访问私有成员
my_string::my_string(const my_string& other)
{printf(" my_string(const my_string & str) = %s \n", other.data);length = other.length;data = new char[length + 1];strcpy(data, other.data);
}//移动构造函数  注意&&  浅拷贝
my_string::my_string(my_string&& other) noexcept
{printf(" my_string(my_string && str) = %s \n", other.data);//不用申请内存 直接进行赋值即可data = other.data;length = other.length;other.data = nullptr;other.length = 0;
}my_string::~my_string()
{printf("~my_string() = %s \n", data);if(data)delete[]data;
}size_t my_string::size() const
{return length;
}const char* my_string::c_str() const
{return data;
}//=  ==  +  <<
//深拷贝 注意对象可能同一个   返回对象的引用  
my_string& my_string::operator = (const my_string& other) noexcept//赋值构造函数 复制
{printf("operator = (const my_string & other) = %s \n", other.data);if (this == &other){return *this;}//赋值 先清理 再赋值delete[]data;length = other.length;data = new char[length + 1];strcpy(data, other.data);return *this;
}//浅拷贝  注意对象可能一个 返回引用
my_string& my_string::operator = (my_string&& other) noexcept //移动赋值构造函数
{printf("operator = (my_string && other) = %s \n", other.data);if (this == &other){return *this;}data = other.data;length = other.length;other.data = nullptr;other.length = 0;return *this;  //返回对象的引用  
}//判断两个字符串相等 
bool  my_string::operator==(const my_string& other) const
{printf("operator==(const my_string &other) = %s \n", other.data);return strcmp(data, other.data) == 0;
}my_string my_string::operator +(const my_string& other) const
{printf("operator +(const my_string & other) = %s \n", other.data);my_string NewString;NewString.length = length + other.length;NewString.data = new char[NewString.length + 1];strcpy(NewString.data, data);strcpy(NewString.data, other.data);return NewString; //函数中定义的对象   返回该拷贝
}

注意operator<< 和operator>>和friend的细节。

//输出 
std::ostream& operator <<(std::ostream& os, const my_string& str)
{os << str.data;return os;
}
std::istream& operator>>(std::istream& in,  my_string& str)
{//或者按行输入获取字符串const size_t BUFFER_SIZE = 1024;char buffer[BUFFER_SIZE] = { 0 };in >> buffer;str.length = strlen(buffer);delete[] str.data; //理论上都是已有对象进行输入 str.data = new char[str.length + 1];strcpy(str.data, buffer);return in;
}

3.3 测试代码

int main()
{//默认构造函数测试my_string str; //默认构造函数my_string str_c("c string");  //c字符串构造my_string str_str(str_c);   //拷贝构造吧printf("size = %d dara = %s \n", str_str.size(), str_str.c_str());my_string str_move(std::move(str_str)); //移动语义if (str_str.c_str() == nullptr){printf("size = %d dara = nullptr \n", str_str.size());}printf("size = %d dara = %s \n", str_move.size(), str_move.c_str());std::cout << "\nos =" << str_move << std::endl;
//直接初始化 my_string str_move1 = std::move(str_move);std::cout << "\nstr_move1  =" << str_move1 << std::endl;//std::cout << "\nstr_move  =" << str_move << std::endl;//赋值构造my_string str_cp = str_move1;std::cout << "\nstr_move1 =" << str_move1 << std::endl;std::cout << "\nstr_cp =" << str_cp << std::endl;
//赋值初始化 my_string str_cp_by_operator;my_string str_move_by_operator;str_cp_by_operator = str_cp;std::cout << "\nstr_cp_by_operator =" << str_cp_by_operator << std::endl;std::cout << "str_cp =" << str_cp << std::endl;str_move_by_operator = std::move(str_cp);std::cout << "\nstr_move_by_operator =" << str_cp_by_operator << std::endl;if (str_cp.c_str() != nullptr){std::cout << "str_cp =" << str_cp << std::endl;}if (str_cp_by_operator == str_move_by_operator){printf("\n operator ==  is success! \n");}else{printf("\n operator ==  is failed! \n");}my_string add = str_cp_by_operator + str_move_by_operator;std::cout << "add =" << add << std::endl;printf("please input str:==>");std::cin >> str;std::cout << "os =" << str << std::endl;return 0;
}

3.4:结合结果分析:

在这里插入图片描述

相关文章:

日常知识点之面试后反思裸写string类

1&#xff1a;实现一个字符串类。 简单汇总 最简单的方案&#xff0c;使用一个字符串指针&#xff0c;以及实际字符串长度即可。 参考stl的实现&#xff0c;为了提升string的性能&#xff0c;实际上单纯的字符串指针和实际长度是不够了&#xff0c;如上&#xff0c;有优化方案…...

(2025)深度分析DeepSeek-R1开源的6种蒸馏模型之间的逻辑处理和编写代码能力区别以及配置要求,并与ChatGPT进行对比(附本地部署教程)

(2025)通过Ollama光速部署本地DeepSeek-R1模型(支持Windows10/11)_deepseek猫娘咒语-CSDN博客文章浏览阅读1k次&#xff0c;点赞19次&#xff0c;收藏9次。通过Ollama光速部署本地DeepSeek-R1(支持Windows10/11)_deepseek猫娘咒语https://blog.csdn.net/m0_70478643/article/de…...

zyNo.22

常见Web漏洞解析 命令执行漏洞 1.Bash与CMD常用命令 &#xff08;1&#xff09;Bash 读取文件&#xff1a;最常见的命令cat flag 在 Bash 中&#xff0c;cat 以及的tac、nl、more、head、less、tail、od、pr 均为文件读取相关命令&#xff0c;它们的区别如下&#xff1a; …...

博客项目-day05(首页导航栏功能补全)

导航 其实之前已经实现过文章和标签分类了 但是这个对应的是导航栏的&#xff0c;多显示个图片 所以新增两个这个请求 文章分类 把之前的CategoryVo加个描述属性 写过这个copyList,直接用就行 标签分类 和上面的分类查询差不多 不多解释了 分类文章列表 点击这个后…...

防御保护-----前言

HCIE安全防御 前言 计算机病毒 ​ 蠕虫病毒----->具备蠕虫特性的病毒&#xff1a;1&#xff0c;繁殖性特别强&#xff08;自我繁殖&#xff09;&#xff1b;2&#xff0c;具备破坏性 蠕虫病毒是一种常见的计算机病毒&#xff0c;其名称来源于它的传播方式类似于自然界中…...

力扣刷题(数组篇)

日期类 #pragma once#include <iostream> #include <assert.h> using namespace std;class Date { public:// 构造会频繁调用&#xff0c;所以直接放在类里面&#xff08;类里面的成员函数默认为内联&#xff09;Date(int year 1, int month 1, int day 1)//构…...

初一说明文:我的护眼灯

本文转自&#xff1a;AI范文助手网 原文链接&#xff1a;https://www.aazhushou.com/czzw/5023.html 自爱迪生发明了灯以来&#xff0c;各种各样的灯相继问世了&#xff0c;给人一种新景象&#xff0c;其中护眼灯也问世了。 我有一盏台灯叫麦迪格护眼灯。那天我和母亲去商场&…...

【论文阅读】Revisiting the Assumption of Latent Separability for Backdoor Defenses

https://github.com/Unispac/Circumventing-Backdoor-Defenses 摘要和介绍 在各种后门毒化攻击中&#xff0c;来自目标类别的毒化样本和干净样本通常在潜在空间中形成两个分离的簇。 这种潜在的分离性非常普遍&#xff0c;甚至在防御研究中成为了一种默认假设&#xff0c;我…...

八一南昌起义纪念塔手绘图纸:一部凝固的工程史诗

在南昌美术馆的玻璃展柜中&#xff0c;泛黄的八一南昌起义纪念塔手绘图纸正无声述说着一段工程奇迹。这些诞生于上世纪七十年代的图纸&#xff0c;以0.05毫米的针管笔触勾勒出总高53.6米的纪念碑&#xff0c;在硫酸纸上构建的坐标网格精确到毫米级&#xff0c;每一根结构线都暗…...

[hgame 2025 ]week1 pwn/crypto

一共两周&#xff0c;第一周说难也不难说简单也不简单。 pwn counting petals 数组v7长度17&#xff0c;输入16时v7[161]会发生溢出&#xff0c;溢出到v8,v9,将其改大&#xff0c;会输出canary和libc_start_main_ret的地址。第2次进来覆盖到返回地址写上ROP from pwn import…...

python 获取smpl身高 fbx身高

目录 python 获取smpl身高 读取fbx,获取fbx mesh身高 python 获取smpl身高 video_segments = pickle.load(open(smpl_pkl_path, "rb"))if isinstance(video_segments, tuple):video_segments = video_segments[0]scene = bpy.data.scenes[Scene]ob, obname, arm_o…...

实战教程:如何利用DeepSeek结合深度学习与NLP技术实现跨模态搜索与个性化推荐

跨模态搜索与个性化推荐是当前人工智能领域中的热门话题,DeepSeek作为结合深度学习与自然语言处理(NLP)技术的创新平台,提供了在多模态数据间进行搜索与推荐的强大能力。本教程将带你一步步实现基于DeepSeek的跨模态搜索和个性化推荐,详细讲解整个过程的实现方法,从数据准…...

计算机毕业设计Python+卷积神经网络租房推荐系统 租房大屏可视化 租房爬虫 hadoop spark 58同城租房爬虫 房源推荐系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

目标检测模型性能评估:mAP50、mAP50-95、Precision 和 Recall 及测试集质量的重要性

目标检测评估全解析&#xff1a;从核心指标到高质量测试集构建 目标检测技术在计算机视觉领域发挥着至关重要的作用&#xff0c;无论是自动驾驶、安防监控&#xff0c;还是医学影像处理&#xff0c;目标检测算法的性能评估都需要依赖一系列精确且科学的评估指标。而测试集的构建…...

AnyPlace:学习机器人操作的泛化目标放置

25年2月来自多伦多大学、Vector Inst、上海交大等机构的论文“AnyPlace: Learning Generalized Object Placement for Robot Manipulation”。 由于目标几何形状和放置的配置多种多样&#xff0c;因此在机器人任务中放置目标本身就具有挑战性。为了解决这个问题&#xff0c;An…...

2025icpc(Ⅱ)网络赛补题 GL

题意&#xff1a; 给定Alice和Bob的每一轮的概率p0,p1 给定Alice和Bob的初始数字x,y。 对于每一轮&#xff1a; 如果Alice获胜&#xff0c;则bob的数字y需要减去x。&#xff08;如果y≤0&#xff0c;Alice获胜&#xff09;如果Bob获胜&#xff0c;则Alice的数字x需要减去y。…...

51c大模型~合集112

我自己的原文哦~ https://blog.51cto.com/whaosoft/13267449 #Guidance-Free Training (GFT) 无需引导采样&#xff0c;清华大学提出视觉模型训练新范式 引导采样 Classifier-Free Guidance&#xff08;CFG&#xff09;一直以来都是视觉生成模型中的关键技术。然而最近&am…...

Rust 文件读取:实现我们的 “迷你 grep”

1. 准备示例文件 首先&#xff0c;在项目根目录&#xff08;与 Cargo.toml 同级&#xff09;下新建一个名为 poem.txt 的文件。示例内容可参考 Emily Dickinson 的诗&#xff1a; Im nobody! Who are you? Are you nobody, too? Then theres a pair of us — dont tell! Th…...

【Unity3D】Jenkins Pipeline流水线自动构建Apk

目录 一、准备阶段 二、创建Pipeline流水线项目 三、注意事项 一、准备阶段 1、安装tomcat 10.0.5 Index of apache-local/tomcat/tomcat-10 2、安装jdk 17 Java Archive Downloads - Java SE 17.0.13 and later 3、下载Jenkins 2.492.1 (.war)包 War Jenkins Packa…...

信息收集-Web应用备案产权Whois反查域名枚举DNS记录证书特征相似查询

知识点&#xff1a; 1、信息收集-Web应用-机构产权&域名相关性 2、信息收集-Web应用-DNS&证书&枚举子域名 企业信息 天眼查 https://www.tianyancha.com/ 企业信息 小蓝本 https://www.xiaolanben.com/ 企业信息 爱企查 https://aiqicha.baidu.com/ 企业信息 企查…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...