2025年c++ 条件变量 wait(c++ 条件变量和读写锁)

c++ 条件变量 wait(c++ 条件变量和读写锁)感谢您阅读本篇文章 文章内容是个人学习笔记的整理 如果哪里有误的话还请您指正噢 个人主页 余辉 zmh CSDN 博客 文章所属专栏 c 篇 CSDN 博客 在上一篇文章中 我们了解到了类的常用接口函数以及如何熟练使用 在这片文章中 我们将深入探讨如何模拟实现一个基本的类 我们的目的不是创建一个功能完整的库 而是通过这个过程来学习字符串处理的基本原理和常见的实现技巧 通过模拟实现类 我们不仅能够深入理解字符串的内部工作原理 还能锻炼我们的编程能力 提高解决问题的能力



✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨
✨ 个人主页:余辉zmh–CSDN博客
✨文章所属专栏:c++篇–CSDN博客

在这里插入图片描述

在上一篇文章中,我们了解到了类的常用接口函数以及如何熟练使用。在这片文章中,我们将深入探讨如何模拟实现一个基本的类。我们的目的不是创建一个功能完整的库,而是通过这个过程来学习字符串处理的基本原理和常见的实现技巧。通过模拟实现类,我们不仅能够深入理解字符串的内部工作原理,还能锻炼我们的编程能力,提高解决问题的能力,希望这篇文章能过为你的编程之旅提供有价值的参考和启发。

注意:模拟实现string类需要用到三个文件

  • 文件用来进行测试
  • 文件用来定义接口函数(部分较为短小的函数将会直接在文件中定义)
  • 文件用来声明头文件和string类

为了和库里面的类进行区分,我们首先定义一个命名空间用来封装我们自己模拟实现的类。

基本框架如下:


  • r在堆上开辟动态内存用来存储string对象的数据。
  • 用来记录string对象的实际大小。
  • 用来记录当前string对象可存储的最大容量。
  • 是一个无符号整形的最大值,在查找等相关函数会用到。

前面我们知道,一个类中有六个默认成员函数(在我之前的文章类和对象(二)中有关于默认成员函数的详细讲解,不清楚的可以看我之前的文章),在模拟实现string类时,我们只需要实现常用的四个(构造函数,析构函数,拷贝构造函数,赋值运算符重载)即可。

1.构造函数

  • 代码实现:

  • 实现原理:

    • str字符串作为常量参数用来创建string对象,缺省值为空字符串(当没有参数时就是创建一个空对象),缺省值要在声明中给,不能再定义中给。
    • _size字符串大小和_capacity容量初始化值为参数str字符串的大小(strlen(str))。
    • _str指针用来指向存储string对象的动态内存,开辟空间的大小为参数str字符串的大小加一,加一是为了存放结尾的’0’,开辟空间后要将str字符串内容拷贝到开辟的动态内存。

2.析构函数

  • 代码实现:

  • 实现原理:

    • 释放动态内存空间,再将_str指针置为空指针。
    • _size字符串大小和_capacity容量置为0。

3.拷贝构造函数(深拷贝)

  • 代码实现:

  • 实现原理:

    • 用一个string对象拷贝构造一个新的string对象,拷贝构造函数需要完成深拷贝。
    • 先用字符串s的容量作为新空间的大小申请一个新的动态内存空间,再将s字符串的数据拷贝到新的内存空间中。
    • 新的string对象的_size和_capacity分别是原string对象的_size和_capacity.

4.赋值运算符重载(深拷贝)

  • 代码实现:

  • 实现原理:

    • 赋值和拷贝构造的不同点在于,拷贝构造是用已有的对象拷贝构造一个新的对象;而赋值是用一个已存在的对象赋值给另一个已存在的对象,赋值也是需要完成深拷贝。
    • 先用赋值对象s的容量大小申请一个新的动态内存空间,设置一个新的tmp指针先指向这块空间,再将赋值对象s的数据拷贝到新的内存空间中。
    • 释放被赋值对象的原有空间,再将被赋值对象的_str指针指向新的内存空间。
    • 被赋值对象的_size和_capacity分别是赋值对象s的_size和_capacity.

深拷贝(Deep Copy)是对象复制操作中的一种,它不仅仅复制对象的表层数据(如指针或引用),还会递归地复制对象内部所有动态分配的内存、引用的其他对象或其他资源。这样,复制出来的新对象与原始对象在内存中是完全独立的,对它们的修改不会影响到彼此。

深拷贝的必要性

当对象包含指向动态分配内存的指针或其他需要管理的资源时,浅拷贝(仅复制指针值)会导致两个对象共享同一块内存。这可能会引发以下问题:

  1. 数据损坏:一个对象修改了它共享的内存中的数据,导致另一个对象看到的数据也发生了变化。
  2. 内存泄漏:如果两个对象都认为自己拥有这块内存,并在析构时尝试释放它,就会导致重复释放内存的错误(double free),进而可能导致程序崩溃。
  3. 资源管理混乱:如果对象还管理其他资源(如文件句柄、网络连接等),共享这些资源可能会导致资源被意外关闭或重复访问。

深拷贝的实现

实现深拷贝通常涉及以下几个步骤:

  1. 为新对象分配内存:如果原始对象包含动态分配的内存,深拷贝的第一步是为新对象分配相应的内存空间。
  2. 复制数据:将原始对象中的数据复制到新分配的内存中。如果数据本身也是对象(即对象包含指向其他对象的指针),则需要递归地应用深拷贝。
  3. 更新指针:将新对象的指针成员指向新分配的内存,而不是原始对象的内存。
  4. 处理其他资源:如果对象管理其他资源(如文件、网络连接等),则需要确保新对象也能正确地获取或创建这些资源的副本。

测试代码如下:


测试结果如下:

在这里插入图片描述

  • 函数代码实现:

  • 函数代码实现:

1.普通对象的迭代器

  • 类型定义:

  • 函数代码实现:

  • 函数代码实现:

2. 对象的迭代器

  • 类型定义:

  • 函数代码实现:

  • 函数代码实现:

测试代码如下:


测试结果如下:

在这里插入图片描述

获取string对象的大小需要使用size()函数,获取容量则需要使用capacity()函数

  • 函数代码实现:

  • 函数代码实现:

类扩容相关的函数主要是和。

  • 函数代码实现:

  • 实现原理:

    • 首先判断需要扩容的大小n是否大于原容量大小_capacity,如果小于则不进行扩容,大于时就需要扩容。
    • 扩容时先开辟内存大小为(n+1)的动态内存空间,在设置一个新的字符指针tmp指向新的内存空间,然后将原string对象的数据拷贝到新的内存空间中。
    • 释放原string对象的_str指针,再从新指向开辟的新内存空间,最后更改内存大小为n。
  • 函数代码实现:

  • 实现原理:

    • 首先依然是需要判断扩容的大小n是否大于原容量大小_capacity,和reserve()函数不同的是,resize对于扩容大小n小于原容量大小时会发生截断,大于时就会进行扩容操作,这里扩容操作直接调用reserve()函数即可。

    • 如果扩容大小n大于原string对象的_size,需要将多余的空间初始化为参数ch,参数ch的缺省值设置为’0’(要在声明中给),没有传参时,默认初始化为0。

测试代码如下:


测设结果如下:

在这里插入图片描述

  • 1.push_back()函数实现:

     

    2.实现原理:

    • push_back()函数的功能是尾插单个字符,在尾插之前要先判断是否需要扩容,在扩容时,如果需要尾插的string对象是空对象扩容 大小先设置为4,如果不是空对象则扩容大小是原容量的二倍,扩容直接调用reserve()函数即可。
    • 插入时,将原来字符串的’0’位置存放插入的字符ch,再将大小_size增加一,最后重新在字符串的结尾加上’0’。
  • 1.函数实现:

    append()函数有两种不同的实现,一个是在原对象后增加单个字符,一个是增加字符串。

     

    2.实现原理:

    • 增加单个字符直接调用push_back函数。
    • 增加字符串时,先获取插入字符串的大小len,然后判断原字符串的大小加上插入字符串的大小是否大于容量_capacity,如果大于需要先进行扩容,扩容大小为原字符串的大小加上插入字符串的大小。
    • 将插入的字符串拷贝到原字符串后面,拷贝大小为len+1,然后修改_size值。
  • 1.函数实现:

    函数和函数一样有两种不同的实现,在原对象后增加单个字符和字符串。

     

    2.实现原理:

    • 增加单个字符直接调用push_back()函数,最后要返回this指针。
    • 增加字符串直接调用append(const char* str)函数,最后返回this指针。
  • 函数实现:

    1.插入n个字符:

     

    实现原理:

    • 如果原字符串大小加上插入的个数大于容量大小时,需要先进行扩容,扩容大小为原字符串大小加上插入的个数。
    • 将插入位置后面的数据依次往后移动n个位置。
    • 再将移动后空出来的位置插入n个字符ch。最后修改_size大小。

    2.插入字符串:

     

    实现原理:

    • 插入字符串和插入n个字符原理相同,不同点是,最后插入时,需要依次插入字符串的字符。
  • 函数实现:

  • 实现原理:

    • 删除要分为两种情况,第一种,如果删除的个数大于_size或者len等于npos值,直接从pos位置将后面全部删除。
    • 第二种,依次将后面的字符往前移动,从而达到删除的目的。

测试代码如下:


测试结果如下:

在这里插入图片描述

  • 1.流插入函数实现:

  • 1.流提取函数实现:

测试代码如下:


在这里插入图片描述






以上就是关于如何模拟实现string类的讲解,如果哪里有错的话,可以在评论区指正,也欢迎大家一起讨论学习,如果对你的学习有帮助的话,点点赞关注支持一下吧!!!
在这里插入图片描述

编程小号
上一篇 2025-03-17 20:33
下一篇 2025-03-04 11:21

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/36511.html