【C++】面试题:模拟实现string类(版本一:用深度拷贝来实现 )

C++深拷贝与浅拷贝详解:从内存泄漏到现代最佳实践 在C++编程中,对象拷贝是一个基础且关键的操作,其底层实现方式直接决定了程序的健壮性与安全性。拷贝的核心原理在于如何处理对象持有的资源,特别是动态分配的内存。默认的成员逐一复制(浅拷贝)仅复制指针值,导致多个对象共享同一资源,从而引发悬垂指针、重复释放等严重问题。为了解决这些问题,需要实现深拷贝,即为新对象创建资源的独立副本。这项技术对于管理动态内存、文件句柄或网络套接字的类至关重要,是避免内存泄漏和程序崩溃的基石。在实际开发中,无论是配置VSCode进行C++环境搭建的新手,还是研读《深入浅出C++》的进 阅读详情

    在学习C++时,我们发现string这个类功能很强大,所以我们模拟实现以下它,虽然不能像库函数里实现的那么强大和完美,但是有助于我们更加熟悉的使用string。此篇博客我将用深度拷贝来实现。这里深度拷贝简单来说就是除了拷贝对象的值以外,若对象有其所指向的一块空间,则同时为新创建的对象也开辟一块空间,再拷贝内容。除了深度拷贝,写时拷贝也能实现string类,并且写时拷贝更加高效,写时拷贝具体是什么,我将再下篇用写时拷贝实现string类进行介绍。

    这里我简单的实现了string类的基本函数和几个功能函数:

#define _CRT_SECURE_NO_WARNINGS 1 
#include<iostream>
#include<cstring>
#include<cassert>
using namespace std;

class String
{
	friend ostream& operator<<(ostream &os, const String &s);
public:
	String(char *str = "")
		:_str(new char[strlen(str) + 1]), _sz(strlen(str)), _capacity(strlen(str) + 1)
	{
		strcpy(_str, str);
	}
	~String()
	{
		if (_str != NULL)
		{
			delete[] _str;
			_sz = 0;
			_capacity = 0;
		}
	}
	String(const String &s)
		:_str(new char[strlen(s._str) + 1])
	{
		_sz = s._sz;
		_capacity = s._capacity;
		strcpy(_str, s._str);
	}
	String& operator=(String s)     //赋值运算符重载的现代写法
	{
		_sz = s._sz;
		_capacity = s._capacity;
		std::swap(s._str, _str);
		return *this;
	}
	const char *c_str()
	{
		return _str;
	}
	void CheckCapacity(int sz)   //检测容量是否够用,不够则重新开辟
	{
		int tmp = 0;

		if (_capacity<(sz + _sz + 1))
		{
			tmp = (2 * _capacity > _capacity + sz) ? 2 * _capacity : _capacity + sz;
			char *str = new char[_capacity];
			strcpy(str, _str);
			delete[] _str;
			_str = new char[tmp];
			strcpy(_str, str);
			_capacity = tmp;
		}
	}
	void PushBack(char ch)          //尾部插入字符
	{
		CheckCapacity(1);
		_str[_sz++] = ch;
		_str[_sz] = '\0';
		_sz += 1;
	}
	char operator[](int sz)
	{
		return _str[sz];
	}
	String &operator+=(const String&s)
	{
		CheckCapacity(strlen(s._str));
		strcat(_str, s._str);
		return *this;
	}
	size_t find(const String& s, size_t pos = 0) const  //在一个字符串里查找子串,返回第一次出现的位置下标
	{
		char *str1 = _str;
		char *src = _str;
		char *str2 = s._str;
		int count = 1;
		while (*src)
		{
			str2 = s._str;
			str1 = src;
			
			while ((*str1) && (*str2) && (*str1 == *str2))
			{
				str1++;
				str2++;
			}
			if (*str2 == '\0')
			{
				return count;
			}

			count++;
			src++;
		}
		return 0;
	}
	String& Insert(size_t pos1, const String& s)  //给定位置插入字符串
	{
		//assert((pos1 > 0) || (pos1 < strlen(_str + 1)));
		CheckCapacity(strlen(s._str));
		char *tmp = new char[strlen(_str)];
		strcpy(tmp, _str + pos1-1);
		_str[pos1 - 1] = '\0';
		*this += s;
		strcat(_str, tmp);
		_sz += strlen(s._str);
		return *this;
	}
private:
	char *_str;
	int _sz;
	int _capacity;
};

ostream& operator<<(ostream &os, const String &s)
{
	os << s._str;
	return os;
}

void test1()  //测试拷贝构造
{
	String s1("hello");
	String s2(s1);
	cout << s2 << endl;
}

void test2()  //测试赋值操作符
{
	String s1("hello");
	String s2;
	s2 = s1;
	cout << s2 << endl;
}

void test3()  //测试+=操作符重载
{
	String s1("hello");
	String s2(" world");
	s1 += s2;
	cout << s1 << endl;
}

void test4()  //测试pushback函数
{
	String s1("worl");
	s1.PushBack('d');
	cout << s1 << endl;
}

void test5()  //测试find函数
{
	String s1("hello world");
	String s2("world");
	int ret = s1.find(s2);
	cout << ret << endl;
}

void test6()   //测试[]运算符重载
{
	String s1("hello world");
	cout << s1[2] << endl;
}

void test7()  //测试insert函数
{
	String s1("hello");
	s1 = s1.Insert(2, " world");
	cout << s1 << endl;
}
int main()
{
	test1();
	test2();
	test3();
	test4();
	test5();
	test6();
	test7();
	getchar();
	return 0;
}

    私有成员除了一个char* 类型的字符串,还有一个_sz(字符串的长度)和_capacity(字符串开辟空间的大小)来维护字符串。在需要插入字符或者字符串的时候,需要先检测空间大小是否足够,不够则需要重新开辟空间,这时候需要用到_sz,_capacity。

    除了以上这些功能,库里的string其实有更多的功能,感兴趣可以点击这个链接自己搜索看看:http://www.cplusplus.com/

C++二叉树实现:从节点设计到深拷贝与内存管理 二叉树是数据结构与算法中的核心概念,它通过节点与指针的链接关系,构建出层次化的数据组织方式。其递归遍历、比较与变换等操作,深刻体现了分治思想在程序设计中的应用价值。在C++工程实践中,实现一个功能完整的二叉树类,是理解指针操作、递归逻辑和资源安全管理的绝佳场景。本文聚焦于二叉树在C++中的具体实现,深入探讨了使用模板进行泛型设计、通过递归实现深拷贝与镜像生成等关键操作,并详细分析了如何遵循“三大件”规则(拷贝构造、赋值运算符、析构函数)来避免浅拷贝陷阱和内存泄漏,确保程序的健壮性。这些内容对于夯实C++基础 阅读详情

相关推荐

大厂C++面试真题深度解析:从智能指针到单例模式的实战代码与设计思想

在C++编程领域,理解核心概念如RAII(资源获取即初始化)和设计模式是构建健壮、高效软件的基础。RAII通过将资源生命周期与对象绑定,确保了资源的自动管理,是现代C++资源管理的核心理念。其技术价值在于从根本上防止了资源泄漏,并简化了异常安全编程。这一原理广泛应用于智能指针、文件句柄管理等场景。设计模式则提供了解决常见软件设计问题的可复用方案,例如单例模式确保一个类仅有一个实例,并提供了全局访问点。在并发编程、配置管理等需要全局唯一资源的场景中,单例模式尤为重要。本文聚焦于C++面试中的高频真题,通过解析

weixin_42525551的博客 246

【C++】9道经典面试题带你玩转string类

9道关于string类的经典面试题目:包含把字符串转换成整数(atoi),字符串相加,反转字符串,字符串中的第一个唯一字符,字符串最后一个单词的长度,验证回文串,反转字符串 II,反转字符串中的单词 III,字符串相乘等经典题目的解题思路及完整解题代码.

C/C++领域,数据结构,linux,MySQl学习者 1512

C++ STL stack容器适配器:从LIFO原理到底层deque实现深度解析

栈(Stack)是计算机科学中一种基础且重要的数据结构,其核心遵循后进先出(LIFO)原则。在C++标准模板库(STL)中,stack并非独立容器,而是一个精妙的容器适配器,它通过封装底层序列容器(如deque、vector或list),仅暴露符合栈语义的接口,实现了逻辑与存储的解耦。这种设计体现了代码复用与灵活性的工程思想,使得stack在处理具有“最近相关性”的问题时,如函数调用栈管理、括号匹配、表达式求值等场景,能提供高效且安全的操作。本文聚焦于stack的底层实现,深入探讨了其默认选择deque作为

weixin_30596023的博客 391

C++ 考察基础经典面试题:string类的基础设计

文章目录前引C++ 经典基础面试题:string类的基础设计1、题目(原型代码)1、String::String(const char* str) 构造函数2、String::String(const String& other) 拷贝构造函数3、String::~String 析构函数4、String& String::operator= (const String& other) 赋值函数5、String String::operator+ (const String&

Love 6's Private Blog 983

自己总结的面试题字符串

自己总结的面试常见题 C++字符串处理 自己总结的面试常见题 C++字符串处理

CDR学习笔记——02

这篇写一些高级CDR的架构原理。

... 1017

String 常见面试题和解析

1、String为什么是不可变字符串?但是我们在实际应用中 String是可以被改变的,能详细说一下嘛? 不可变字符串主要是: 保存字符串的数组被final修饰并且是私有的,并且 String 类没有提供和暴露修改这个字符串的方法。 String 类被 final修饰不能被子类继承,进而避免了子类破坏 String不可变。 实际中可变的原因: 其实并不是改变 String ,是新创建了一个 String 对象指向改变后的值,原本的 String 成为副本字符串对象存留在内存中。 2、String str

weixin_43281498的博客 5136

实现高精度卷积混响--MATLAB仿真篇

一、前言 之前在STM32F407上现实了直播声卡,实现的经典Schroeder混响模型和Moorer混响模型,得到不错效果。后来得知卷积混响最为真实地表现空间的特性,所以也就尝试在MCU上实现一个高精度的卷积混响(卷积点数为32768),目前MCU出来的混响效果算得上一流水准,本人也在计划在ADI的21489或者SC584上更高精度的卷积混响。 二、卷积方式 1、conv1是使用MATLAB自带卷积函数conv 2、conv2和conv3是改进后卷积过程,具有减少运算量特点,方便嵌入式移植 clear;

Six44的博客 5082

c++ 实现自己的string 类[大厂面试必考题]

又是幻想进鹅厂的一天 o(╥﹏╥)o 实现自己的string 类 stl 的string类实现的功能是太多了,咱们就实现几个基本的功能 1. 有参构造 2. 拷贝构造 3. = 赋值重载 4. = 对象赋值重写 5. << 重载 6. [] 重载 用到这俩 变量 1.无参数构造 2.有参数构造 3.拷贝构造 这里说一下 为啥加 const 和 & 加 &...

shenmingyi.blog.youkuaiyun.com 1445

【Unity】YooAsset + HybridCLR热更

本文介绍了Unity游戏开发中的热更新技术方案,重点对比了资源热更和代码热更的主流工具。资源热更方面分析了Asset Bundle、Addressable和YooAsset的优缺点;代码热更部分比较了xLua、ILRuntime、InjectFix和HybridCLR的性能特点。文章详细演示了HybridCLR+YooAsset的实践方案,包括加载热更新程序集、反射调用热更代码、资源打包部署等完整流程。该方案通过原生运行时实现程序集级热更,具有极低性能损耗和全生命周期适用性,配合YooAsset简化了资源管

欢迎指错||纠正||建议||水评+点赞&&评论&&关注&&转发 2919

点云从入门到精通技术详解100篇-点云的特征检测(续)

对每个维度的序列分别计算 DTW 距离,最后。权重将距离限制在较小的范围内,对于时间跨度大的数据集,过度限制了点对点的路径,同的,因此不能用欧氏距离来计算两个多元时间序列之间的距离,本文选用的是动态时。到的股票数据是未知分类的,因此该数据的相似性分析缺少有效的评价方式,通常需要。时间序列,简而言之,就是与时间相关的数据的集合,应用在生活工作中的方方面。时间序列的分段线性化表示的难点在于如何找出分段点,目前,对于分段点的研究。经过分段线性化之后,每个多元时间序列的维度是相同的,但是每一维的长度是不。

getusushu的博客 334

【经典面试题】C++实现String类

String的默认构造函数,构造函数,拷贝构造函数,析构函数,赋值构造函数 #ifndef STRING_H_ #define STRING_H_ class String { public: String(); String(const char *str); String(const String &rhs); ...

danxibaoxxx的博客 393

linux平台Modbus TCP测试

【代码】linux平台Modbus TCP测试。

无线互联&网络介绍 818

C++中的string类【详细分析及模拟实现】

本文从stirng的介绍及使用谈起,详细介绍其各类接口及用法,并针对它们深度剖析并模拟实现,详细介绍模拟实现中程序设计的思路,最后分析了在不同环境下(VS和g++下)string结构情况

kevvviinn的博客 3067

YOLOv11改进策略【模型轻量化】| 替换轻量化骨干网络:ShuffleNet V1

本文记录的是基于ShuffleNet V1的YOLOv11轻量化改进方法研究。ShuffleNet利用和操作降低计算成本,克服了现有先进架构在极小网络中因 1×1 卷积计算成本高而效率低的问题。相比一些传统的网络架构,能更好地。本文配置了原论文中和四种模型,以满足不同的需求。

Limiiiing的博客 1231

用 Custom Entity 打造 RAP Value Help:从能跑到好用的深度踩坑笔记

本文介绍了在RAP项目中实现Value Help(Fiori输入帮助)的完整流程。通过Custom Entity方式,开发者可以灵活构建不依赖数据库实体的值帮助功能,但需手动实现CDS原本提供的过滤、排序、分页等能力。文章以一个典型场景为例,详细说明了如何为Partner维护界面的City字段创建可搜索的值帮助,包括创建查询实现类、绑定CDS Custom Entity、服务发布等关键步骤,并特别指出了处理排序分页请求等常见问题。最后强调在ABAP Cloud环境下需要自行实现查询能力,而非依赖传统工具类。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 140

8.string类-下:string类的模拟实现【由浅入深-C++】

本文介绍string类的模拟实现。

插花弄玉的博客 709

IEEE Journal of Biomedical and Health Informatics(JBHI)投稿经验分享

《IEEE Journal of Biomedical and Health Informatics投稿经验分享》详细记录了在影响因子6.7的中科院一区期刊JBHI的投稿历程(2025.1-5月,历时4个月)。文章重点分析:1)审稿特色:4位审稿人差异显著,领域专家意见专业但要求严苛;2)修改要点:需重视大修(补充实验/原理阐述),并注意将回复内容同步至正文;3)期刊特点:送审率高但审稿严格,常规投稿周期约4-5个月;4)实用建议:建议首次大修全力以赴,善用AI工具辅助写作,避免拖延。

LiRongLu_的博客 5091

C++ String类模拟实现:从RAII到深拷贝的底层原理剖析

在C++编程中,动态内存管理是理解现代C++核心机制的关键基础。通过RAII(Resource Acquisition Is Initialization)原则,开发者可以确保资源在对象生命周期内被安全获取与释放,避免内存泄漏和悬垂指针。这一原理在标准库容器如std::string中得到了经典应用,通过封装字符数组指针、大小与容量,实现了高效的字符串操作。其技术价值在于将复杂的内存管理抽象为简单的对象使用,显著提升代码安全性与可维护性。在模拟实现自定义String类的过程中,开发者需直面深拷贝与浅拷贝的核心

weixin_30225755的博客 276

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++ string类深度解析:从入门到面试通关

✅ 为什么学习string类:C语言字符串操作不符合OOP思想,且容易出错 ✅ string类的常用接口:构造、容量操作、访问遍历、修改操作等 ✅ string的底层结构:vs下28字节(SSO优化) vs g++下4字节(写时拷贝) ✅ 浅拷贝与深拷贝:浅拷贝导致多个对象共享同一资源,深拷贝让每个对象拥有独立资源 ✅ 传统版与现代版String实现:现代版利用swap更简洁高效 ✅ 写时拷贝:通过引用计数实现资源延迟拷贝

2303_77004089的博客 360

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C++面试题之数据结构和算法

目录 1、String原理及实现 2、链表的实现 2.1、顺序链表 2.2、链式表 2.3、双链表 2.4、循环链表 3、队列 3.1、顺序队列 3.2、链式队列 4、栈 4.1、顺序栈 4.2、链式栈 5、二叉树 5.1、二叉树的链式存储 5.2、哈夫曼树 6、查找算法 6.1、线性表查找(顺序查找、折半查找) 6.2、树表查找(二叉排序树、平衡二叉树、B-树...

找个特立不独行的名的博客 2万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

13-string(3)

【代码】13-string(3)

m0_73582663的博客 104

C++ STL vector模拟实现:从内存管理到迭代器失效的深度解析

在C++编程中,STL(标准模板库)是构建高效应用程序的核心基础,而vector作为最常用的序列容器,其动态数组特性广泛应用于数据存储与管理。理解vector的底层原理,关键在于掌握其内存管理机制:通过三段式指针(起始、结束、容量边界)实现动态扩容,并遵循RAII原则确保资源安全。从技术价值看,手动实现vector不仅能深入理解拷贝控制、异常安全等C++核心概念,还能优化性能,例如通过移动语义和完美转发提升效率。在实际应用场景中,vector的高频操作如push_back、insert等常涉及迭代器失效问题

weixin_34056162的博客 479

C++ vector模拟实现:从内存管理到迭代器失效的深度解析

在C++编程中,动态数组是管理连续内存数据的基础数据结构,其核心原理涉及内存分配、元素生命周期管理和高效访问机制。通过资源获取即初始化(RAII)原则和模板元编程技术,可以实现类型安全且高效的内存管理。这种技术价值在于为开发者提供了对底层内存操作的完全控制,避免了标准库黑盒带来的理解盲区,尤其在性能优化和调试复杂内存问题时至关重要。应用场景广泛,从嵌入式系统开发到高性能计算,都需要对容器内部机制有深刻理解。本文以模拟实现vector为例,深入探讨了其内存管理策略、迭代器失效问题及异常安全保证,通过实现pus

weixin_34174105的博客 305

C++知识点(1)

自学笔记

qq_62123793的博客 274

C++ STL vector 深度剖析:从入门到面试通关

vector 本质 可变大小数组,连续存储空间,支持随机访问 扩容机制 vs 下 1.5 倍扩容,g++ 下 2 倍扩容,不要固化认知 reserve vs resize reserve 只开空间,resize 开空间 + 初始化 迭代器失效 扩容操作和 erase 后迭代器会失效,需要重新赋值 模拟实现 掌握三个指针管理:_start、_finish、_endofstorage memcpy 问题 涉及资源管理的对象不能用 memcpy 浅拷贝

2303_77004089的博客 398
上一篇: 【C++】实现万年历
下一篇: 【C++】模拟实现string类(版本二:用写时拷贝来实现)
pointer_y
博客等级 码龄11年 157粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值