移动语义和拷贝语义区别、智能指针

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

1.概念

拷贝语义:

在传统的拷贝操作中,当一个对象被赋值给另一个对象或者作为参数传递给一个函数时,会创建源对象的一个副本。例如,在 C++ 中,如果有一个类MyClass,当执行MyClass obj2 = obj1;(这里obj1是已经存在的MyClass对象),编译器会调用拷贝构造函数来创建obj2,它会复制obj1中的所有成员变量的值。这意味着会有新的内存分配(如果成员变量包含指针,还会复制指针所指向的内容),并且两个对象在内存中有各自独立的存储空间,对obj2的修改不会影响obj1。

移动语义:
移动语义是 C++ 11 引入的一个重要特性。它的目的是避免不必要的拷贝,特别是对于那些拥有资源(如动态分配的内存、文件句柄等)的对象。当使用移动语义时,资源的所有权从一个对象转移到另一个对象,而不是复制资源。例如,对于一个包含动态分配数组的类,移动构造函数可以将源对象中的指针直接赋值给目标对象,然后将源对象中的指针置为nullptr,这样就避免了重新分配内存和复制数组元素的开销。

2.区别: 
资源开销方面

拷贝语义:通常会产生较大的资源开销。如果对象包含大量的数据或者复杂的资源(如大型数组、数据库连接等),拷贝操作可能会消耗大量的时间和内存。例如,一个std::vector对象包含大量元素,当进行拷贝时,需要为新的vector对象分配足够的内存空间,然后逐个复制元素。
移动语义:在移动语义下,资源的转移通常比拷贝快得多。因为它只是简单地改变资源的所有权,而不需要复制资源的内容。继续以std::vector为例,移动构造函数可以简单地将内部指针(指向存储元素的内存块)从源vector转移到目标vector,几乎没有数据复制的开销。
对象状态方面

拷贝语义:源对象和目标对象在拷贝操作后都是有效的,并且它们是相互独立的。源对象的状态在拷贝后保持不变。
移动语义:在移动操作后,源对象通常处于一种 “可析构但可能部分无效” 的状态。例如,一个被移动的std::string对象,它内部的字符数组指针可能被置为nullptr,但对象本身仍然可以被正确地析构(因为析构函数知道如何处理这种情况)。
使用场景方面

拷贝语义:适用于需要独立副本的情况,比如当你想要对一个对象进行修改,但又不希望影响原始对象时,或者当对象的生命周期和作用域要求有独立的副本时。例如,在一个函数中需要对传入的参数进行一些计算,但又不希望改变原始参数的值,就可以使用拷贝语义。
移动语义:在函数返回大型对象或者对象之间转移资源所有权时非常有用。例如,一个函数返回一个动态分配的大型数据结构,使用移动语义可以避免将数据复制一份,从而提高性能。

 二、c++智能指针


在 C++ 中,智能指针是一种用于管理动态分配内存的对象。它们的行为类似于常规指针,但提供了自动内存管理的功能。智能指针的主要目的是帮助防止内存泄漏,因为它们会自动释放所指向的内存,当智能指针对象的生命周期结束时(例如,当它超出作用域时),它所管理的内存会被自动释放。
类型
std::unique_ptr
独占所有权:std::unique_ptr表示独占所有权,即一个对象只能有一个unique_ptr指向它。它不能被复制,但可以被移动。例如:

std::unique_ptr<int> ptr1 = std::make_unique<int>(5);
// 正确的移动操作
std::unique_ptr<int> ptr2 = std::move(ptr1);
// 错误的复制操作
// std::unique_ptr<int> ptr3 = ptr2; 
  • 应用场景:适用于大多数情况下的单一所有者资源管理,比如当一个对象在某个函数或代码块内独占使用一块动态分配的内存时。
  • std::shared_ptr
    • 共享所有权std::shared_ptr实现了共享所有权的语义。多个shared_ptr可以指向同一个对象,并且对象的生命周期会被自动管理,直到最后一个指向它的shared_ptr被销毁。它使用引用计数来跟踪有多少个shared_ptr指向同一个对象。例如:

 

std::shared_ptr<int> ptr3 = std::make_shared<int>(10);
std::shared_ptr<int> ptr4 = ptr3;
  • 应用场景:当多个部分的代码需要共享访问同一个动态分配的对象时,比如在一个复杂的数据结构中,多个节点可能需要共享某些资源,就可以使用shared_ptr
  • std::weak_ptr
    • 弱引用std::weak_ptr是一种弱引用,它通常和shared_ptr一起使用。weak_ptr不会增加所引用对象的引用计数,主要用于解决shared_ptr可能导致的循环引用问题。例如,在一个对象图结构中,两个对象可能通过shared_ptr相互引用,这会导致它们的引用计数永远不会降为 0,从而无法被正确释放。使用weak_ptr可以打破这种循环。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/476647.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024信创数据库TOP30之蚂蚁集团OceanBase

数据库作为存储、管理和分析这些数据的关键工具&#xff0c;其地位自然不言而喻。随着信息技术的日新月异&#xff0c;数据库技术也在不断演进&#xff0c;以满足日益复杂多变的市场需求。近日&#xff0c;备受瞩目的“2024信创数据库TOP30”榜单由DBC联合CIW/CIS权威发布&…

Kafka 生产者优化与数据处理经验

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

【强化学习的数学原理】第02课-贝尔曼公式-笔记

学习资料&#xff1a;bilibili 西湖大学赵世钰老师的【强化学习的数学原理】课程。链接&#xff1a;强化学习的数学原理 西湖大学 赵世钰 文章目录 一、为什么return重要&#xff1f;如何计算return&#xff1f;二、state value的定义三、Bellman公式的详细推导四、公式向量形式…

006-自定义枚举注解

自定义枚举注解 一、业务需求描述1.问题描述2.解决方案 二、创建一个描述注解三、创建一个枚举注解四、创建一个枚举五、创建一个配置文件六、场景实战1.在 RequestParam 前面使用2.在非 Model 的实体类上使用3.在 RequestBody 对应的实体类中使用 七、效果展示 一、业务需求描…

数据库表设计范式

华子目录 MYSQL库表设计&#xff1a;范式第一范式&#xff08;1NF&#xff09;第二范式&#xff08;2NF&#xff09;第三范式&#xff08;3NF&#xff09;三范式小结巴斯-科德范式&#xff08;BCNF&#xff09;第四范式&#xff08;4NF&#xff09;第五范式&#xff08;5NF&…

力扣刷题--21.合并两个有序链表

I am the best &#xff01;&#xff01;&#xff01; 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2…

【java-Neo4j 5开发入门篇】-最新Java开发Neo4j

系列文章目录 前言 上一篇文章讲解了Neo4j的基本使用&#xff0c;本篇文章对Java操作Neo4j进行入门级别的阐述&#xff0c;方便读者快速上手对Neo4j的开发。 一、开发环境与代码 1.docker 部署Neo4j #这里使用docker部署Neo4j,需要镜像加速的需要自行配置 docker run --name…

三层交换机静态路由实验

1、前置知识 2、实验目的 3、实验器材&#xff1a; 3560-23PS交换机2台、主机4台、交叉线1根和直通网线4根。 4、实验规划及拓扑 实验要求&#xff1a; &#xff08;1&#xff09;在交换机A和交换机B上分别划分基于端口的VLAN&#xff1a; 交换机 VLAN 端口成员 交换机…

基于Java Springboot付费自习室管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

深度学习笔记24_天气预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 一、我的环境 1.语言环境&#xff1a;Python 3.9 2.编译器&#xff1a;Pycharm 3.深度学习环境&#xff1a;TensorFlow 2.10.0 二、GPU设置…

node报错:Error: Cannot find module ‘express‘

报错信息&#xff1a; Error: Cannot find module express 分析原因&#xff1a; 项目中需要express工具&#xff0c;但是import引入不进来&#xff0c;说明在这个项目中我们本没有对express工具包进行install&#xff0c;从我们项目中的package.json也可以看到&#xff08;并…

【课堂笔记】隐私计算实训营第四期:“隐语”可信隐私计算开源框架

“隐语”可信隐私计算开源框架 隐语架构一览隐语架构拆解产品层算法层PSI/PIR数据分析&#xff08;Data Analysis&#xff09;联邦学习&#xff08;Federated Learning&#xff09; 计算层混合编译调度——RayFedSPUHEUTEEUYACL 资源层KUSCIA 互联互通跨域管控 隐语架构一览 隐…

Halo 正式开源: 使用可穿戴设备进行开源健康追踪

在飞速发展的可穿戴技术领域&#xff0c;我们正处于一个十字路口——市场上充斥着各式时尚、功能丰富的设备&#xff0c;声称能够彻底改变我们对健康和健身的方式。 然而&#xff0c;在这些光鲜的外观和营销宣传背后&#xff0c;隐藏着一个令人担忧的现实&#xff1a;大多数这些…

Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字化时代&#xff0c;…

嵌入式中利用QT实现服务器与客户端方法

大家好,今天主要给大家分享一下,如何使用QT中TCP协议进行传输控制,它是一种面向连接的,可靠的基于字节流的传输层控制协议。 第一:Linux中网络通信简介 TCP通信必须建立TCP连接,通信端分为客户端和服务端。服务端通过监听某个端口来监听是否有客户端连接进来,如果有连接…

网络安全,文明上网(6)网安相关法律

列举 1. 《中华人民共和国网络安全法》&#xff1a; - 这是中国网络安全的基本法律&#xff0c;于2017年6月1日开始实施。该法律明确了网络运营者的安全保护义务&#xff0c;包括采取数据分类、重要数据备份和加密等措施。 2. 《中华人民共和国数据安全法》&#xff1a; …

Vscode写markdown快速插入python代码

如图当我按下快捷键CRTLSHIFTK 自动出现python代码片段 配置方法shortcuts’ 打开这个json文件 输入 {"key": "ctrlshiftk","command": "editor.action.insertSnippet","when": "editorTextFocus","args&…

【前端】第12节:Vue3新特性

引入 说起 vue3 的新特性&#xff0c;就会不由自主想到 vue3 和 vue2 之间的差异&#xff0c;例如&#xff1a;双向绑定、根节点数量、生命周期、this 等等&#xff0c;详细可以见这篇文章&#xff08;参考&#xff09;—— vue2和vue3的差异整理&#xff08;轻松过度到vue3&a…

Linux 进程概念与进程状态

目录 1. 冯诺依曼体系结构2. 操作系统&#xff08;Operator System&#xff09;2.1 概念2.2 设计OS的目的2.3 系统调用和库函数概念 3. 进程概念3.1 描述进程 - PCB3.2 task_struct3.3 查看进程3.4 通过系统调用获取进程标识符PID&#xff0c; PPID3.5 通过系统调用创建fork 4.…

滑动窗口篇——如行云流水般的高效解法与智能之道(1)

前言&#xff1a; 上篇我们介绍了双指针算法&#xff0c;并结合具体题目进行了详细的运用讲解。本篇我们将会了解滑动窗口。滑动窗口是一种常用的算法技巧&#xff0c;主要用于处理子数组、子串等具有“窗口”特性的题目。柳暗花明&#xff0c;乃巧解复杂问题的高效之道。 一. …