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

C++ 拷贝构造函数和重载赋值运算符

一、为什么需要拷贝构造函数和重载拷贝运算符?先了解深拷贝和浅拷贝。

在 C++ 中,深拷贝(Deep Copy)浅拷贝(Shallow Copy)是两种完全不同的对象拷贝方式,它们的核心区别在于如何处理指针或动态分配的资源。以下是详细对比:

1. 浅拷贝(Shallow Copy)

定义
  • 逐字节复制:直接复制对象的所有成员变量的值(包括指针地址)。

  • 不创建新资源:拷贝后的对象和原对象共享同一块动态内存或资源

    class String {
    public:char* data;  // 动态分配的字符数组String(const char* str = "") {data = new char[strlen(str) + 1];strcpy(data, str);}// 默认拷贝构造函数是浅拷贝!
    };int main() {String s1("Hello");String s2 = s1;  // 浅拷贝:s2.data 和 s1.data 指向同一内存s2.data[0] = 'X';  // 修改 s2 会影响 s1!std::cout << s1.data;  // 输出 "Xello"(本不应被修改)
    }
    问题
  • 双重释放:两个对象析构时会尝试释放同一块内存,导致崩溃。

  • 数据意外共享:一个对象的修改会影响另一个对象。

2. 深拷贝(Deep Copy)

  • 定义
  • 创建新资源:为新对象独立分配内存,并复制原对象指向的实际数据。

  • 完全独立:拷贝后的对象和原对象不共享任何资源

实现方式

---> 需自定义拷贝构造函数和赋值运算符

class String {
public:char* data;// 深拷贝构造函数String(const String& other) {data = new char[strlen(other.data) + 1];  // 新分配内存strcpy(data, other.data);                 // 复制数据}// 深拷贝赋值运算符String& operator=(const String& other) {if (this != &other) {  // 自赋值检查delete[] data;     // 释放旧资源data = new char[strlen(other.data) + 1];strcpy(data, other.data);}return *this;}~String() { delete[] data; }
};int main() {String s1("Hello");String s2 = s1;  // 深拷贝:s2.data 是新分配的内存s2.data[0] = 'X';  // 修改 s2 不会影响 s1std::cout << s1.data;  // 输出 "Hello"(保持原样)
}
优点
  • 避免资源冲突:每个对象拥有独立资源。

  • 安全析构:不会双重释放内存。

3. 关键对比

特性浅拷贝深拷贝
拷贝内容复制指针地址(共享资源)复制指针指向的实际数据(独立资源)
资源管理危险(需外部协调释放)安全(每个对象管理自己的资源)
默认行为C++ 默认提供需手动实现
性能快(仅复制指针)慢(需分配内存+复制数据)
典型问题双重释放、数据竞争
适用场景仅限无资源的简单类管理资源的类

 二、拷贝构造函数 与 赋值运算符

1、拷贝构造函数

  • 在以下情况被调用:

    String s1("Hello");
    String s2 = s1;  // 拷贝构造(初始化)
    String s3(s1);   // 拷贝构造

    用于对象的初始化(从另一个对象创建新对象)

2.重载赋值运算符 

在以下情况被调用:

String s1("Hello");
String s2;
s2 = s1;  // 拷贝赋值(已存在对象被覆盖)

用于已存在对象的赋值(覆盖原有值)。


示例:仅实现拷贝构造的缺陷

class String {char* data;
public:String(const char* str) { /* 分配内存 */ }String(const String& other) { /* 深拷贝 */ }  // 实现了拷贝构造~String() { delete[] data; }// 未实现 operator=
};int main() {String s1("Hello");String s2("World");s2 = s1;  // 使用默认的 operator=,浅拷贝!// s2 的原始内存泄漏,且 s1 和 s2 指向同一内存
}

结果:程序崩溃(双重释放)或内存泄漏。

补充:在C++中,将 拷贝构造函数(Copy Constructor) 和 赋值运算符(Copy Assignment Operator) 声明为 private(私有)的主要作用是 禁止类的对象被拷贝或赋值。这是C++中一种常用的设计技巧,通常用于控制对象的复制行为。

在C++中,private 成员(包括构造函数)只能被类的成员函数或友元访问


http://www.mrgr.cn/news/100620.html

相关文章:

  • VLM-E2E:通过多模态驾驶员注意融合增强端到端自动驾驶——论文阅读
  • 一键叠图工具
  • ES练习册
  • LangChain入门(二)安装开发环境
  • 【Git】项目多个分支开发、维护与优化处理 ing
  • 3、CMake语法:制作和使用动态库和静态库
  • 细说fork-vfork-pthread_create-clone
  • 【dify+docker安装教程】
  • 八大排序——冒泡排序/归并排序
  • 【云计算】云计算中IaaS、PaaS、SaaS介绍
  • 安卓基础(点击项目)
  • 高能效计算:破解算力增长与能源约束的科技密码
  • 夜莺监控V8(Nightingale)二进制部署教程(保姆级)
  • 微分与积分(前言)
  • WPF之Label控件详解
  • VUE3:封装一个评论回复组件
  • 1.7无穷级数
  • Uniapp(vue):生命周期
  • InitializingBean接口和@PostConstruct-笔记
  • SpringBoot启动后自动执行方法的各种方式-笔记