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

《C++》STL--string详解(下)

文章目录

  • 一、深浅拷贝定义
    • 1.1 浅拷贝的本质
    • 1.2 内存示意图
    • 1.3 深拷贝的本质
    • 1.4 内存示意图
  • 二、用拷贝实现string类
    • 2.1 浅拷贝实现的String类
    • 2.2 深拷贝实现的String类
    • 2.3 总结

一、深浅拷贝定义

1.1 浅拷贝的本质

  • 浅拷贝就像复印一张名片时,只复制了名片上的地址信息,而没有复制地址对应的实际房屋。在C++中表现为:
class ShallowString {
public:char* data;// 构造函数ShallowString(const char* str = "") {data = new char[strlen(str)+1];strcpy(data, str);}// 问题:没有自定义拷贝构造函数
};ShallowString s1("hello");
ShallowString s2 = s1;  // 默认浅拷贝

1.2 内存示意图

s1.data → "hello\0"↑
s2.data ───┘

1.3 深拷贝的本质

  • 深拷贝则是完全复制整栋房屋。在C++中需要显式实现:
class DeepString {
public:char* data;// 构造函数DeepString(const char* str = "") {data = new char[strlen(str)+1];strcpy(data, str);}// 深拷贝构造函数DeepString(const DeepString& other) {data = new char[strlen(other.data)+1];strcpy(data, other.data);}
};DeepString s1("hello");
DeepString s2 = s1;  // 深拷贝

1.4 内存示意图

s1.data → "hello\0"
s2.data → "hello\0"  // 完全独立的内存

可见,用大白话来说,深拷贝就是拥有自己的内存,而浅拷贝非也

二、用拷贝实现string类

2.1 浅拷贝实现的String类

#include <cstring>
#include <iostream>class ShallowString {
private:char* m_data;size_t m_size;public:// 构造函数ShallowString(const char* str = "") {m_size = strlen(str);m_data = new char[m_size + 1];strcpy(m_data, str);}// 析构函数~ShallowString() {delete[] m_data;}// 打印字符串内容void print() const {std::cout << m_data << std::endl;}// 修改字符串内容void modify(size_t pos, char c) {if (pos < m_size) {m_data[pos] = c;}}
};void demoShallowCopyProblem() {ShallowString s1("hello");ShallowString s2 = s1; std::cout << "修改前:" << std::endl;s1.print();  // 输出: hellos2.print();  // 输出: hellos2.modify(0, 'H');  // 修改s2std::cout << "修改后:" << std::endl;s1.print();  // 输出: Hello (不应该被修改)s2.print();  // 输出: Hello}

当然,本文单开肯定也是有道理的,上面的代码是错误的awa, 因为在程序结束时会导致双重释放错误!

  • 浅拷贝问题分析:

    • 拷贝时只复制了指针值,导致多个对象共享同一内存

    • 修改一个对象会影响其他对象

    • 析构时会导致同一内存被多次释放

2.2 深拷贝实现的String类

那么正确的版本,在下文

class DeepString {
private:char* m_data;size_t m_size;public:// 构造函数DeepString(const char* str = "") {m_size = strlen(str);m_data = new char[m_size + 1];strcpy(m_data, str);}// 拷贝构造函数(深拷贝)DeepString(const DeepString& other) {m_size = other.m_size;m_data = new char[m_size + 1];strcpy(m_data, other.m_data);}// 拷贝赋值运算符(深拷贝)DeepString& operator=(const DeepString& other) {if (this != &other) {  // 防止自赋值delete[] m_data;    // 释放原有内存m_size = other.m_size;m_data = new char[m_size + 1];strcpy(m_data, other.m_data);}return *this;}// 析构函数~DeepString() {delete[] m_data;}// 打印字符串内容void print() const {std::cout << m_data << std::endl;}// 修改字符串内容void modify(size_t pos, char c) {if (pos < m_size) {m_data[pos] = c;}}
};// 演示深拷贝的正确性
void demoDeepCopy() {DeepString s1("hello");DeepString s2 = s1;  // 深拷贝std::cout << "修改前:" << std::endl;s1.print();  // 输出: hellos2.print();  // 输出: hellos2.modify(0, 'H');  // 修改s2std::cout << "修改后:" << std::endl;s1.print();  // 输出: hello (不受影响)s2.print();  // 输出: Hello// 程序结束时正确释放内存
}

2.3 总结

  • 必须自定义拷贝构造函数和拷贝赋值运算符

  • 在拷贝时分配新内存并复制内容

  • 注意处理自赋值情况

http://www.lryc.cn/news/602414.html

相关文章:

  • 代码随想录算法训练营二十九天|动态规划part02
  • QML QtCharts 饼状图(PieSeries)
  • AI资讯日报 - 2025年07月28日
  • Vue3 学习教程,从入门到精通, Vue 3 表单语法知识点及案例详解(19)
  • MDM五十万台设备高并发场景解决方案【后台管理】
  • Django + Celery 详细解析:构建高效的异步任务队列
  • 负载均衡算法中的加权随机算法
  • 【pytest高阶】源码的走读方法及插件hook
  • 端到端的核心区别点
  • 标准SQL语句示例
  • 【力扣热题100】哈希——两数之和
  • 数据库概述(学习笔记)
  • 能源智跃:大模型破壁数据孤岛,铸就智能转型新范式
  • 腾讯云centos7使用docker部署生产环境中间件
  • 力扣 hot100 Day58
  • eclipse更改jdk环境和生成webservice客户端代码
  • STM32入门之DMA直接存储器存取
  • 雷达系统设计学习:自制6GHz FMCW Radar
  • 从单枪匹马到联盟共生:白钰玮的 IP 破局之路|创客匠人
  • 【智慧物联网平台】编译jar环境 Linux 系统Maven 安装——仙盟创梦IDE
  • 2025创始人IP如何破局?
  • 【智慧物联网平台】编译jar环境 Linux 系统编译IOT物联网——仙盟创梦IDE
  • 解构远程智能系统的视频能力链:从RTSP|RTMP协议接入到Unity3D头显呈现全流程指南
  • Ansible安装与入门
  • WPF,按钮透明背景实现MouseEnter
  • 【Linux】Ubuntu上安装.NET 9运行时与ASP.NET Core项目部署入门
  • C#/.NET/.NET Core技术前沿周刊 | 第 48 期(2025年7.21-7.27)
  • 1.gradle安装(mac)
  • 基于AFLFast的fuzz自动化漏洞挖掘(1)
  • 全新AI工具小程序源码 全开源