C++ 赋值运算符重载 & const成员

本文详细解析C++中的运算符重载概念,尤其是赋值运算符的重载,包括参数类型、返回值、自赋值检测及返回*this的重要性。同时,深入探讨const成员函数的使用,解释其如何限制this指针,确保成员函数不修改类的任何成员。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、赋值运算符的重载
1、运算符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字:关键字operator后面接需要重载的运算符符号
函数原型: operator+操作符(const 类类型名& d);

注意:
(1)不能通过连接其他符号来创建新的操作符:比如operator@
(2)重载操作符必须有一个类类型或者枚举类型的操作数
(3)用于内置类型的操作符,其含义不能改变
(4)作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的 操作符有一个默认的形参this,限定为第一个形参 。
(5).* 、:: 、sizeof 、?: 、. 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。

2、赋值运算符的重载
主要有四点:
(1)参数类型
(2)返回值
(3)检测是否自己给自己赋值
(4)返回*this
(5) 一个类如果没有显式定义赋值运算符重载,编译器也会生成一个,完成对象按字节序的值拷贝

二、const成员
const修饰类的成员函数
将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this 指针,表明在该成员函数中不能对类的任何成员进行修改

<think>我们正在讨论C++中的赋值运算符重载,特别是与深拷贝和浅拷贝相关的内容。用户可能希望了解如何正确重载赋值运算符,避免浅拷贝带来的问题(如双重释放、内存泄漏等),并理解深拷贝与浅拷贝的区别。同时,用户引用的资料中提到了拷贝构造函数和禁止拷贝的方法,这些内容与赋值运算符重载紧密相关。回答结构:1.赋值运算符重载的基本概念和作用2.深拷贝与浅拷贝的区别及问题3.赋值运算符重载的典型写法(包括处理自赋值和释放原有资源)4.拷贝构造函数和赋值运算符的协同(拷贝交换技法)5.何时需要自定义赋值运算符重载6.如何禁止拷贝和赋值(使用delete)7.代码示例8.注意事项9.相关问题注意:根据用户提供的引用,引用[2]展示了深拷贝的拷贝构造函数,引用[3]展示了如何禁止拷贝,引用[4]说明了赋值运算符重载必须是成员函数以及默认行为(浅拷贝)。下面开始回答:</think> ### C++赋值运算符重载(Operator Overloading)使用指南 赋值运算符重载(`operator=`)是控制类对象拷贝行为的核心机制。正确实现可避免**浅拷贝**导致的资源泄漏或数据损坏,尤其涉及动态内存管理时[^1][^4]。 --- #### 一、核心概念 | **类型** | **特点** | **风险** | |----------------|--------------------------------------------------------------------------|------------------------------| | **浅拷贝** | 逐字节复制指针地址(编译器默认生成) | 多个对象共享资源 → 双重释放崩溃 | | **深拷贝** | 创建资源的新副本(需手动实现) | 无共享资源 → 安全但消耗更大 | | **禁止拷贝** | 用 `= delete` 显式删除拷贝操作 | 完全阻止拷贝行为 | --- #### 二、赋值运算符重载规范写法 ##### 1. 基本结构 ```cpp class MyClass { public: // 深拷贝赋值运算符 MyClass& operator=(const MyClass& other) { if (this != &other) { // 关键:检查自赋值! // 1. 释放原有资源 delete[] data; // 2. 深拷贝新资源 data = new int[other.size]; size = other.size; std::copy(other.data, other.data + size, data); } return *this; // 支持链式赋值 (a=b=c) } private: int* data; size_t size; }; ``` ##### 2. 处理自赋值与异常安全 ```cpp MyClass& operator=(const MyClass& other) { if (this != &other) { int* new_data = new int[other.size]; // 先创建新资源 std::copy(other.data, other.data + other.size, new_data); delete[] data; // 再释放旧资源 (异常安全) data = new_data; // 无异常再赋值 size = other.size; } return *this; } ``` > **为什么检查自赋值?** > 防止 `a=a` 时误释放自身资源 → 访问已释放内存崩溃[^4]。 --- #### 三、深度拷贝完整示例 ```cpp #include <iostream> #include <algorithm> class Vector { public: // 构造函数 Vector(size_t n) : size(n), data(new int[n]{}) {} // 深拷贝赋值 Vector& operator=(const Vector& other) { if (this != &other) { int* new_data = new int[other.size]; std::copy(other.data, other.data + other.size, new_data); delete[] data; data = new_data; size = other.size; } return *this; } // 析构函数 ~Vector() { delete[] data; } void print() { for (size_t i = 0; i < size; ++i) std::cout << data[i] << " "; std::cout << "\n"; } private: int* data; size_t size; }; int main() { Vector v1(3); // 初始化为 [0,0,0] Vector v2(2); // 初始化为 [0,0] v1 = v2; // 深拷贝赋值 v2 = v2; // 自赋值安全 } ``` --- #### 四、禁止拷贝的实现 当类不应被拷贝时(如管理唯一资源),显式删除拷贝操作: ```cpp class UniqueResource { public: UniqueResource() = default; // 删除拷贝构造和赋值 UniqueResource(const UniqueResource&) = delete; // [^3] UniqueResource& operator=(const UniqueResource&) = delete; // [^3] // 允许移动语义 UniqueResource(UniqueResource&&) noexcept = default; }; ``` --- #### 五、关键注意事项 1. **返回类型**:必须返回 `Class&`(支持链式赋值 `a=b=c`)[^4] 2. **自赋值检查**:避免 `if (this == &other) return *this;` 逻辑错误 3. **异常安全**:先分配新资源再释放旧资源 4. **协同拷贝构造**:深拷贝类需同时定义 `拷贝构造函数` 和 `operator=`[^2] 5. **移动语义**:C++11+ 中优先实现移动赋值 (`operator=&&`) 提升性能 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值