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

【C++】拷贝构造函数、赋值重载函数、深拷贝及浅拷贝 模拟实现顺序栈和环形队列的问题及理解

拷贝构造函数:用已有对象初始化新对象。

Person p2(p1) Person p2 = p1

赋值运算符:将已有对象赋值给另一个已存在的对象 p1=p2

浅拷贝:只复制指针值,共享内存 默认的拷贝/赋值行为

深拷贝:复制指针指向的内容,独立内存 需要自定义实现

!!!总结:只要类中有动态分配的内存(new),就必须实现:

·拷贝构造函数(深拷贝) 创建新的对象

·赋值运算符重载(深拷贝) 给已存在的对象赋值

拷贝构造vs赋值重载

// 拷贝构造:创建新对象

SeqStack s1;

SeqStack s2 = s1;// ←拷贝构造(s2是新对象)

SeqStack s3(s1);// ←拷贝构造(s3是新对象)

// 赋值重载:已存在的对象赋值

SeqStack s1;

SeqStack s2;// s2已经存在

s2 = s1;// ←赋值重载(s2已存在)

// 关键区别:

// 拷贝构造:不需要释放旧资源(新对象没有)

// 赋值重载:需要释放旧资源(对象已有资源)

·析构函数(释放资源)

浅拷贝:Eg:

class Person { public: Person(const char* name, int age) { this->name = new char[strlen(name) + 1]; strcpy(this->name, name); this->age = age; } ~Person() { delete[] this->name; // 释放内存 } private: char* name; int age; }; int main() { Person per1("赵云", 23); Person per2(per1); // 使用默认拷贝构造函数(浅拷贝) // 问题:per1和per2的name指针指向同一块内存 // 析构时同一块内存被释放两次 → 程序崩溃! return 0; }

深拷贝:Eg:

class Person { public: // 构造函数 Person(const char* name, int age, char sex) { this->name = new char[strlen(name) + 1]; strcpy(this->name, name); this->age = age; this->sex = sex; } // 拷贝构造函数:深拷贝 // 参数必须是引用,否则会无限递归 Person(const Person& rhs) { cout << "Person(const Person& rhs)" << endl; // 重新开辟独立的内存空间 this->name = new char[strlen(rhs.name) + 1]; strcpy(this->name, rhs.name); this->age = rhs.age; this->sex = rhs.sex; } // 析构函数 ~Person() { delete[] this->name; this->name = nullptr; } private: char* name; int age; char sex; }; int main() { Person per1("赵云", 23, 'M'); Person per2(per1); // 调用拷贝构造函数,深拷贝 // per1和per2的name指向不同的内存,互不影响 return 0; }

模拟实现顺序栈和环形队列遇到的问题总结:

  1. 模拟实现堆:mTop始终指向栈顶元素的下一个元素,因此出栈直接mTop--,就是指向栈顶元素假装此位置为空没有元素,伪删。
  2. 判满:bool full() { return mTop == mSize; } // 元素个数 == 容量,因为mTop刚好指向下一个元素,所以数值上可以和mSize相比。

3.模拟实现和环形队列:front_:指向队头元素(第一个有效元素)

rear_:指向队尾的下一个位置(下一个要放的位置)

4.,环形移动:

// 入队:rear_ 环形后移 void push(int data) { queue_[rear_] = data; rear_ = (rear_ + 1) % size_; // 取模实现环形 } // 出队:front_ 环形后移 void pop() { front_ = (front_ + 1) % size_; // 取模实现环形 }

5.判满(rear_ + 1) % size_ == front_

浪费一个空间的原因是区分空和满。

6.!!!扩容时为什么 rear_ = count?

因为扩容前队列的环形的 rear可能在front前,顺序不对,而扩容之后赋值过程中count的增加suoyinindex从front开始,此时队列变成顺序的,因此rear刚好在count的位置。

http://www.jsqmd.com/news/1403830/

相关文章:

  • Spring Boot 动态配置把服务拖慢:限制刷新范围并准备回退
  • 2026年8月保定外墙漏水维修防水公司推荐,高层高空渗水修缮避坑指南 - 聪居到家
  • Ubuntu 22.04 部署 Elastic Stack:APT 安装与生产环境调优指南
  • 升级完车灯才懂!宿迁这家十年改灯老店排队是有原因的 - Ayu8888
  • 2026年8月温江阳台漏水维修|阳台外墙渗水、推拉窗漏水、阳台过门石渗水修缮实操指南 - 超人防水
  • 从零到点亮第一盏灯:OpenPLC Editor 免费 PLC 编程环境的实战手册
  • 每日极客日报 · 2026年08月15日
  • 终极一站式Switch模拟器管理工具
  • Vue 3 全栈应用止损:功能开关、错误边界与回滚
  • 内景 现代 展厅 太空舱
  • Grok 4.6 长时运行智能体开发实战:解决AI失忆与状态持久化难题
  • MyEclipse 2023 安装配置全攻略:从环境搭建到项目部署
  • 前程无忧最新校招服务的收费标准是什么样的?
  • 外景 西域风格建筑窑洞
  • Kubernetes 节点卡顿:CPU Throttle、I/O 与调度怎么查
  • 商丘带肋钢丝网片/焊接镀锌网片供货商国标规格齐全,非标尺寸也能按需定制加工-美络金属制品 - 行业甄选汇
  • 告别25fps卡顿与两侧黑边:D2DX宽屏高帧率改造工具实战攻略
  • NVIDIA NemoClaw:AI智能体开发平台核心架构与全链路部署实战
  • 烟台家政推荐|家政选购全攻略:看懂服务、避开误区,选到靠谱家政服务 - 收录优先
  • League Akari 上手记:一个开源助手,如何让英雄联盟少掉三成繁琐操作
  • 百元级开源车载机器人:基于树莓派的智能座舱原型开发指南
  • 交付纪实|13 套无纸化升降会议终端项目顺利验收
  • League Akari 免费上手指南:一键自动选人,把英雄联盟的重复操作交给它
  • mpv 播放器终极懒人配置:一份全中文注释的完整折腾记录,够省心吗
  • 大模型产品别只看 Demo:用任务分流和单次贡献毛利算 ROI
  • AIGC 结果上链前怎么拦:Schema 预检、Gas 预算与状态机止损
  • 2026年小型割圈绒针织大圆机制造商实力评估与选型参考 - 卓企推荐
  • ESP8266-Onenet-AT指令工具推荐(由博主代码小A制作)
  • 赤峰防水补漏哪家靠谱? - 用户198513
  • 四足机器人技术栈深度解析:从算法到产品化的工程实践