[C++] 拷贝构造还是赋值重载?类默认成员函数细节详解

C++98中类的默认成员函数有:默认构造函数、析构函数、拷贝构造函数,拷贝赋值,取地址重载

C++11新增了移动构造和移动赋值函数

1. 构造函数

可以参考作者早期发布的文章:

C++:构造函数与初始化列表详解

2. 析构函数

功能:清理释放对象中资源

特点:

  1. 函数名:~类名
  2. 无参数和返回值
  3. 未显式定义,会生成默认析构函数(内置类型:不处理;自定类型:另外调用
  4. 生命周期结束时自动调用
  5. 如果申请了资源,一定要自己显式写析构函数(否则会内存泄漏
  6. 析构顺序:后定义先析构(类似栈

使用示例:

cpp 复制代码
class MyBuffer {
public:
    MyBuffer()
    {
        this->data = new int[10]; 
        std::cout << "MyBuffer()" << std::endl;
    }

    ~MyBuffer()
    {
        delete[] this->data;  //显式实现资源释放
        std::cout << "~MyBuffer()" << std::endl;
    }

private:
    int* data;
};

3. 拷贝构造

功能:根据一个已存在对象构造一个相同的拷贝对象

特点:

  1. 构造函数的重载
  2. 第一个参数是类类型对象引用(传值调用拷贝构造,触发无穷递归调用
  3. 多参数:第一个外的参数必须有缺省值
  4. 自定类型对象进行拷贝时必须调用拷贝构造::即传参/传值都会触发
  5. 如果申请了资源,一定要显式写拷贝构造函数(内置类型:默认浅拷贝,析构时会多次delete同一份资源;自定类型:另外调用
cpp 复制代码
    // 拷贝构造函数:深拷贝
    MyBuffer(const MyBuffer& other)
    {
        this->data = new int[10]; //深拷贝
        for (int i = 0; i < 10; ++i)
        {
            this->data[i] = other.data[i];
        }
    }

结论:自定类型尽量传引用传参(传值触发拷贝构造->深拷贝->浪费内存

4. 运算符重载

功能:支持对象像普通变量一样使用各种运算符

特点 / 注意:

  1. 不能重载:.* :: sizeof ?: . 和语法中没有的符号(eg:@
  2. 函数名:operator运算符(参数数量和返回值类型由运算符本身特性决定
  3. 成员函数:第一个对象默认为this指针,不需要显式传(少一个参数
  4. 前置 / 后置运算符:后置运算符参数增加int形参,方便区分
  5. 重载>><<:必须为全局函数(第一个形参为ostream / istream

4.1 赋值重载

功能:支持已存在对象像普通变量一样赋值(区分拷贝构造

特点:

  1. 参数:const+引用,减少传值拷贝
  2. 返回值:类类型引用(减少拷贝 / 支持连续赋值
  3. 如果申请了资源,一定要显式写赋值重载(默认生成:内置类型浅拷贝;自定类型另外调用
  4. 赋值过程:检查自赋值->释放旧资源->申请新资源->拷贝
  5. 自赋值:释放自己的资源+重新访问拷贝,导致访问野指针
  6. 现代写法:传值传参,额外实现swap函数交换指针指向资源(不需要检查自赋值

使用示例:

cpp 复制代码
    MyBuffer& operator=(const MyBuffer& other)
    {
        if (this != &other) // 1. 检查自赋值
        {
            delete[] this->data;      // 2. 释放当前对象的旧资源
            this->data = new int[10]; // 3. 申请新的资源
            for (int i = 0; i < 10; ++i)
            {
                this->data[i] = other.data[i]; // 4. 拷贝数据
            }
        }
        return *this;
    }

现代写法:

cpp 复制代码
	void swap(...){//...}

    MyBuffer& operator=(MyBuffer other) //传值触发拷贝构造
    { 
        swap(*this, other); //交换指针指向对象
        return *this;
    }

4.2 取地址运算符重载

特点:

  1. 包括普通重载和const重载
  2. 编译器自动生成的已经足够使用
相关推荐
goodlook01231 小时前
opencode调用本地模型一(1.18.30版本安装)
开发语言
菜鸟~noob2332 小时前
【电子战】第14篇:TOA 定位——圆交汇与到达时间【含matlab代码】
开发语言·matlab
汉克老师2 小时前
GESP2026年9月认证C++四级( 第一部分选择题(1~7题)精讲
c++·gesp·小学生·学c++编程
itmigrate2 小时前
Redis 开发高频隐形踩坑记录
开发语言·java-ee
geats人山人海2 小时前
现代c++第二章 字符串
c++
白远山2 小时前
本地游戏代练源码开发实战:架构设计与核心功能实现指南
java·开发语言·架构·需求分析
idealzouhu2 小时前
现代 CMake 依赖管理详解:从构建树、Target 封装到 find_package 工作原理
c++·cmake
aramae3 小时前
Python 使用库:标准库与第三方库实战
服务器·开发语言·windows·python
景熙55233 小时前
14.Java 集合框架从入门到源码万字详解(含 ArrayList/LinkedList/HashMap 源码、泛型通配符、红黑树)
java·开发语言·数据结构·算法