移动语义和拷贝语义的区别以及智能指针

devtools/2024/11/24 3:43:48/

移动语义和拷贝语义的区别

一、概念本质:

拷贝语义
拷贝语义是基于对象的复制操作。当一个对象被拷贝时,会创建一个新的对象,这个新对象的内容是原始对象的完全副本,这意味着新对象和原始对象在内存中有独立的存储空间,并且它们包含相同的值。例如,对于一个包含动态分配内存的类,拷贝语义会重新分配一块新的内存,并将原始对象内存中的数据逐字节地复制到新内存中。
移动语义
移动语义则是一种资源所有权的转移,它主要用于将一个对象通常是临时对象或即将被错毁的对象)的资源(如动态分配的内存文件句柄等)直接转移给另一个对象,而不是进行复制。在移动语义中,源对象在资源转移后通常会处于一种“空”或“无效”的状态,以避免资源的双重使用或错误释放。

二、实现方式:

拷贝语义 - 拷贝构造函数和拷贝赋值运算符

在 C++ 中,拷贝语义通过拷贝构造函数(类名(const 类名&))和拷贝赋值运算符(类名& operator=(const 类名&))来实现。

移动语义 - 移动构造函数和移动赋值运算符

移动语义通过移动构造函数(类名(类名&&))和移动赋值运算符(类名& operator=(类名&&))来实现。

三、性能影响

拷贝语义

对于包含大量资源(如大型数组、复杂对象等)的对象,拷贝语义可能会导致性能开销。因为它需要为新对象分配新的资源,并逐个复制资源中的数
据。例如,当拷贝一个包含大量元素的vector对象时,需要重新分配内存并复制每个元素,这可能会消耗大量的时间和内存空间。


移动语义
移动语义在性能上有很大的优势,特别是对于临时对象或不再需要的对象。它可以快速地将资源从一个对象转移到另一个对象,避免了资源的复制操作。例如,当一个函数返回一个包含大量数据的对象时,通过移动语义可以直接将对象的资源转移给调用者的对象,而不是复制这些数据,从而提高了程序的运行效率。

四、使用场景

拷贝语义
当需要一个对象的完全独立副本时,例如在函数参数传递过程中,如果函数不应该修改原始对象,并且需要在函数内部使用一个独立的副本进行操作,就使用拷贝语义。或者当对象的生命周期需要独立管理,并且每个副本都应该有自己完整的资源时,也使用拷贝语义。
移动语义
移动语义主要用于对象资源的高效转移,比如在函数返回对象时,为了避免不必要的资源复制:或者在对象的生命周期结束时,将其资源转移给其他对象继续使用。例如,在容器类(如vector)中,当重新分配内存或进行元素的移动操作时,移动语义可以有效地转移元素的资源,提高容器操作的性能。

C++ 中的智能指针

在 C++ 中,智能指针是一种用于管理动态分配对象的机制。它的主要目的是帮助程序员自动地管理对象的生命周期,避免内存泄漏(即动态分配的内存没有被正确释放)和悬空指针(指向已经被释放的内存的指针)等问题。智能指针本质上是一个类模板(因为智能指针需要能够管理不同类型的对象以及它的核心功能与所管理对象的具体类型是无关的),它的行为类似于普通指针,但在对象的生命周期管理上更加智能。

C++11 中引入了三种新的智能指针类型:

1.unique ptr

用法:

unique_ptr 是一种独占所有权的智能指针,即同一时间内只能有一个 unique_ptr 指向一个给定的对象。当 unique_ptr 被销毁时,它所指向的对象也会被自动删除。

unique_ptr<int> ptr(new int(10));

2.shared ptr

用法:

shared_ptr 是一种共享所有权的智能指针,即多个 shared_ptr 可以同时指向同一个对象,并且会自动跟踪引用计数。对象的最后一个 shared_ptr 被销毁时,该对象才会被删除。

引用计数机制:shared_ptr 的内部维护了一个引用计数。每当一个新的 shared_ptr 指向同一个对象时,引用计数就会加 1;当一个 shared_ptr 不再指向该对象(例如,通过 reset 操作或者自身被销毁)时,引用计数就会减 1;当引用计数变为 0 时,对象会被自动销毁。

shared_ptr<int> ptr1(new int(20));
shared_ptr<int> ptr2=ptr1;

3.weak ptr

用法:

weak_ptr 是一种不控制对象生命周期的智能指针,它是为了解决 shared_ptr 相互引用导致的循环引用问题而设计的。weak_ptr需要与 shared_ptr 一起使用,它可以从一个shared_ptr 或另一个 weak_ptr 创建,但它不会增加引用计数。

shared_ptr<int> sharedPtr(new int(30));
weak_ptr<int> weakPtr(sharedPtr);

区别:

unique_ptr 用于独占所有权的场景,只能有一个指针指向对象,适用于资源管理。

shared_ptr 用于共享所有权的场景,可以有多个指针指向同一个对象,适用于多个对象需要访问同一资源的情况。

weak_ptr 用于辅助 shared_ptr,解决循环引用问题,不控制对象的生命周期。


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

相关文章

DICOM图像知识:解析如何在DICOM图像中实现多层覆盖层的显示的方法

目录 1. 覆盖层&#xff08;Overlay&#xff09;基础 1.1 覆盖层的定义 1.2 DICOM中的覆盖层表示 2. 解析和处理思路 2.1 提取覆盖层数据 2.2 将覆盖层叠加到图像上 3. 实现示例 4. 注意事项 1. 覆盖层&#xff08;Overlay&#xff09;基础 1.1 覆盖层的定义 覆盖层是…

【LeetCode热题100】栈

这道题一共记录了关于栈的5道题目&#xff1a;删除字符串中所有相邻重复项、比较含退格的字符串、基本计算器II、字符串解码、验证栈序列。 class Solution { public:string removeDuplicates(string s) {string ret;for(auto c : s){if(ret.size() 0 || c ! ret.back()) ret …

easyExcel - 导出合并单元格

目录 前言一、情景介绍二、问题分析三、代码实现四、测试代码 前言 Java-easyExcel入门教程&#xff1a;https://blog.csdn.net/xhmico/article/details/134714025 之前有介绍过如何使用 easyExcel&#xff0c;以及写了两个入门的 demo &#xff0c;这两个 demo 能应付在开发…

数据结构-7.Java. 对象的比较

本篇博客给大家带来的是java对象的比较的知识点, 其中包括 用户自定义类型比较, PriorityQueue的比较方式, 三种比较方法...... 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 .…

IntelliJ IDEA常用快捷键

文章目录 环境快捷键外观编辑移动光标提示查找Live Templates列操作调试运行 环境 Ubuntu 24.04.1IntelliJ IDEA 2024.1.6 快捷键 外观 Alt 1&#xff1a;打开/关闭“项目”窗口&#xff08;即左边的导航窗口&#xff09; Alt 4&#xff1a;打开/关闭“运行”窗口 Alt …

湘潭大学软件工程算法设计与分析考试复习笔记(二)

回顾 湘潭大学软件工程算法设计与分析考试复习笔记&#xff08;一&#xff09; 前言 现在接着昨天的复习。今天复习一下&#xff0c;把人机交互的实验二综述写一下&#xff0c;把实验三的 bug 改一下。 模拟退火 最后热情被消耗殆尽&#xff0c;是这意思吗哈哈。这个模拟退…

sourceTree无效的源路径问题解决

1.点击工具 2.点击选项 3.修改ssh客户端为OpenSSH 4.点击确定&#xff0c;然后重新打开软件

从源头保障电力安全:输电线路动态增容与温度监测技术详解

在电力系统中&#xff0c;输电线路是电能传输的关键环节。然而&#xff0c;当导线温度过高时&#xff0c;会加速导线老化&#xff0c;降低绝缘性能&#xff0c;甚至引发短路、火灾等严重事故&#xff0c;对电网安全运行构成巨大威胁。近日&#xff0c;某地区因持续高温和用电负…