C++(14)—类和对象(中) ④赋值运算符重载

devtools/2025/3/17 6:06:54/

文章目录

  • 一、运算符重载的基本概念
    • 1.1 什么是运算符重载?
    • 1.2 运算符重载的限制
  • 二、运算符重载的实现方式
    • 2.1 成员函数重载
    • 2.2 全局函数重载
  • 三、赋值运算符重载
    • 3.1 赋值运算符重载的作用
    • 3.2 赋值运算符重载的特点
  • 四、深拷贝与浅拷贝
    • 4.1 浅拷贝的问题
    • 4.2 深拷贝的实现
  • 五、常见误区与陷阱
    • 5.1 自赋值问题
    • 5.2 连续赋值支持
  • 六、总结与最佳实践
    • 6.1 核心要点
    • 6.2 最佳实践

一、运算符重载的基本概念

1.1 什么是运算符重载?

运算符重载允许我们为类类型对象定义新的运算符行为。通过重载,可以使类对象像内置类型一样使用运算符。

语法规则:

返回类型 operator运算符(参数列表) {// 运算符逻辑
}
class Date {
public:bool operator==(const Date& d) {return _year == d._year && _month == d._month && _day == d._day;}
};

1.2 运算符重载的限制

  1. 不能创建新运算符:如operator@。
  2. 不能改变内置类型的运算符行为:如int operator+(int x, int y)。
  3. 不能重载的运算符:::、.*、.、sizeof、?:等。

二、运算符重载的实现方式

2.1 成员函数重载

特点:运算符重载作为成员函数时,第一个操作数隐式传递给this指针。适用场景:二元运算符(如+、-)和一元运算符(如++、--)。

示例:

class Date {
public:bool operator==(const Date& d) {return _year == d._year && _month == d._month && _day == d._day;}
};

2.2 全局函数重载

特点:运算符重载作为全局函数时,所有操作数均需显式传递。适用场景:流运算符(如<<、>>)。

示例:

ostream& operator<<(ostream& out, const Date& d) {out << d._year << "-" << d._month << "-" << d._day;return out;
}

三、赋值运算符重载

3.1 赋值运算符重载的作用

赋值运算符重载用于两个已存在对象间的赋值操作,确保资源正确拷贝和释放。

语法规则:

ClassName& operator=(const ClassName& other) {// 赋值逻辑return *this;
}

3.2 赋值运算符重载的特点

  1. 必须为成员函数:确保第一个操作数为当前对象。
  2. 返回当前对象引用:支持连续赋值(如a = b = c)。
  3. 默认生成:若未显式定义,编译器会自动生成默认赋值运算符重载。
class Stack {
private:int* _a;size_t _capacity;public:Stack& operator=(const Stack& other) {if (this != &other) {  // 避免自赋值free(_a);  // 释放原有资源_a = (int*)malloc(other._capacity * sizeof(int));memcpy(_a, other._a, other._capacity * sizeof(int));  // 深拷贝_capacity = other._capacity;}return *this;}
};

四、深拷贝与浅拷贝

4.1 浅拷贝的问题

默认赋值运算符重载对指针成员进行浅拷贝,即仅复制指针地址,而非指向的资源。这会导致以下问题:双重释放:多个对象指向同一块内存,析构时重复释放。悬空指针:一个对象修改或释放资源后,其他对象访问无效内存。

4.2 深拷贝的实现

深拷贝通过为新对象分配独立的内存空间,并复制原对象的内容,避免资源冲突。

示例:

class Stack {
private:int* _a;size_t _capacity;public:Stack& operator=(const Stack& other) {if (this != &other) {  // 避免自赋值free(_a);  // 释放原有资源_a = (int*)malloc(other._capacity * sizeof(int));memcpy(_a, other._a, other._capacity * sizeof(int));  // 深拷贝_capacity = other._capacity;}return *this;}
};

五、常见误区与陷阱

5.1 自赋值问题

在赋值运算符重载中,必须检查自赋值情况,否则可能导致资源释放错误。

cpp
复制
if (this != &other) { // 检查自赋值
// 赋值逻辑
}

5.2 连续赋值支持

赋值运算符重载应返回当前对象引用,以支持连续赋值操作。

cpp
复制
a = b = c; // 连续赋值

六、总结与最佳实践

6.1 核心要点

运算符重载:增强类类型对象的操作灵活性。

赋值运算符重载:确保对象间赋值操作的安全性。

6.2 最佳实践

深拷贝:涉及动态资源时,必须显式实现深拷贝。

自赋值检查:避免资源释放错误。

返回引用:支持连续赋值操作。


http://www.ppmy.cn/devtools/167744.html

相关文章

群体智能优化算法-金豺优化算法(Golden Jackal Optimization, GJO,含Matlab源代码)

摘要 金豺优化算法&#xff08;Golden Jackal Optimization, GJO&#xff09;是一种基于金豺&#xff08;Golden Jackal&#xff09;的群体捕猎行为而提出的新型元启发式算法。该算法通过模拟雄豺与雌豺在狩猎时的协同合作与分工机制&#xff0c;结合莱维&#xff08;Lvy&…

MambaTab:表格数据处理的新利器

——基于结构化状态空间模型的特征增量学习框架 摘要 本文提出MambaTab&#xff0c;一种基于结构化状态空间模型&#xff08;SSM&#xff09;的表格数据处理框架。通过创新的嵌入稳定化设计与轻量化SSM架构&#xff0c;MambaTab在普通监督学习和特征增量学习场景中均表现优异&…

【C语言系列】C语言内存函数

C语言内存函数 一、memcpy使用和模拟实现1.1memcpy函数1.2memcpy函数的模拟实现 二、memmove使用和模拟实现2.1memmove函数2.2memmove函数的模拟实现 三、memset函数的使用3.2memset函数及使用 四、memcmp函数的使用4.1memcmp函数及使用 五、总结memcpy 函数memmove 函数memset…

数据结构与算法-图论-欧拉路径和欧拉回路(有向图和无向图,骑马修栅栏,单词游戏 play on words)详细代码注解

基础前置知识&#xff1a; 有向图&#xff1a; 欧拉路径&#xff1a; 定义&#xff1a;在有向图中&#xff0c;从一个顶点出发&#xff0c;经过每条边恰好一次&#xff0c;并且遍历所有顶点的路径称为有向图的欧拉路径。 特征&#xff1a;有向图存在欧拉路径&#xff0c;当…

【开原宝藏】30天学会CSS - DAY1 第一课

下面提供一个由浅入深、按步骤拆解的示例教程&#xff0c;让你能从零开始&#xff0c;逐步理解并实现带有旋转及悬停动画的社交图标效果。为了更简单明了&#xff0c;以下示例仅创建四个图标&#xff08;Facebook、Twitter、Google、LinkedIn&#xff09;&#xff0c;并在每一步…

不用 Tomcat?SpringBoot 项目用啥代替?

在SpringBoot框架中&#xff0c;我们使用最多的是Tomcat&#xff0c;这是SpringBoot默认的容器技术&#xff0c;而且是内嵌式的Tomcat。 同时&#xff0c;SpringBoot也支持Undertow容器&#xff0c;我们可以很方便的用Undertow替换Tomcat&#xff0c;而Undertow的性能和内存使…

【小沐学Web3D】three.js 加载三维模型(React)

文章目录 1、简介1.1 three.js1.2 react.js 2、three.js React结语 1、简介 1.1 three.js Three.js 是一款 webGL&#xff08;3D绘图标准&#xff09;引擎&#xff0c;可以运行于所有支持 webGL 的浏览器。Three.js 封装了 webGL 底层的 API &#xff0c;为我们提供了高级的…

在 Linux 64 位系统上安装 Oracle 11g R2 数据库的完整指南

linux.x64_11gR2_database 是 Oracle 数据库 11g 第 2 版&#xff08;11g Release 2&#xff09;的安装包&#xff0c;适用于 64 位 Linux 操作系统。这个安装包包含了在 64 位 Linux 系统上安装 Oracle 数据库所需的全部文件和组件。 安装步骤概述 以下是在 Linux 系统上安装…