移动构造函数和拷贝构造函数的使用

news2026/2/15 0:25:46

先理解左值和右值

左值可以被多次使用,它们代表的对象在程序中有一个持久的存在。

右值(Rvalue)

右值(Rvalue)是“即将废弃的值”(Resource Values),通常指的是那些只被用一次就会结束生命周期的对象,它们通常作为临时对象出现。

右值通常代表那些“用后即焚”的资源,它们在完成一次操作后就没有其他用途了。

  • 左值(Lvalue)

    左值(Lvalue)是“存储位置的值”(Location Value),它指的是一个对象的身份、存储位置或者内存地址。左值可以出现在赋值运算的左边或右边。

  • 定义:左值表达式在执行后,会提供一个明确的内存位置。
  • 例子
    • 变量:int a; 中的 a 是一个左值,因为它代表内存中的一个具体位置。
    • 返回左值引用的函数:int& func(); 这样的函数返回一个左值的引用。
  • 定义:右值表达式在执行后,不会提供一个可以再次使用的内存位置。
  • 例子
    • 临时对象:int b = 10; 中的 10 是一个右值,因为它是一个字面量,没有持久的存储位置。
    • 返回右值的函数:如果一个函数返回一个对象而不是引用,那么返回的就是一个右值。

在理解右值引用和移动构造函数

在 C++11 之前,所有的对象要么被当作左值处理,要么被当作右值处理,但没有一种机制可以明确地表示一个对象是“可移动的”。这导致了一些不必要的复制操作,尤其是在涉及到临时对象时。右值引用的引入允许程序员明确地表示一个对象是“即将被销毁”的,从而可以利用移动语义来优化性能。

  • 右值引用只能绑定到右值,不能绑定到左值。
  • 一旦一个对象被移动,它就处于一个未定义的状态,直到它被销毁或者重新赋值。
  • 右值引用通常与 std::move 一起使用,std::move 可以将一个左值转换为右值引用,以便可以利用移动语义。

右值引用

  • 想象你有一个装满旧物品的箱子(右值),你准备扔掉它,但里面有一些物品对别人可能有用。
  • 右值引用就像是一个标记,告诉你 “这个箱子里的东西可以拿走,我不再需要它们了”。
  • 当你使用右值引用时,你实际上是在说 “我知道这个东西是临时的,我只想借用里面的物品,而不是拥有它们”。

移动构造函数

  • 移动构造函数就像是一个回收站,它允许你从即将被扔掉的箱子(临时对象)中回收有用的物品,而不是从商店购买新的。
  • 当你创建一个新对象时,如果提供了一个临时对象给移动构造函数,它会 “拿走” 这个临时对象的资源,而不是复制它们。
  • 这个过程就像是在说 “嘿,如果你要扔掉那个箱子,我可以拿走里面的物品,这样你就不用把它们扔掉了”。

在理解拷贝构造函数和移动构造函数的区别和用法

要调用拷贝构造函数,你可以简单地将一个已经存在的对象作为参数传递给另一个同类型对象的构造函数,或者在函数中以值传递的方式传递对象。下面是一些示例:

### 示例:调用拷贝构造函数

class Widget {
public:
    Widget() {
        std::cout << "Default constructor called." << std::endl;
    }

    Widget(const Widget& other) {
        std::cout << "Copy constructor called." << std::endl;
        // 执行必要的资源拷贝操作
    }

    // 其他成员函数...
};

int main() {
    Widget w1; // 调用默认构造函数
    Widget w2 = w1; // 在这里调用拷贝构造函数
    
    return 0;
}

在这个例子中,`Widget w2 = w1;` 这一行代码将调用 `Widget` 类的拷贝构造函数,以 `w1` 为源创建 `w2` 的副本。

### 示例:移动构造函数

移动构造函数通常用于当你有一个临时对象,并且想要“拿走”它的资源而不是复制它们时。以下是一个移动构造函数的例子:

#include <iostream>
#include <memory>

class Widget {
private:
    std::unique_ptr<int> data;
public:
    Widget() : data(std::make_unique<int>(0)) {
        std::cout << "Default constructor called." << std::endl;
    }

    // 拷贝构造函数
    Widget(const Widget& other) = delete; // 为了示例,删除拷贝构造函数

    // 移动构造函数
    Widget(Widget&& other) noexcept : data(std::move(other.data)) {
        std::cout << "Move constructor called." << std::endl;
    }

    // 其他成员函数...
};

int main() {
    Widget w1; // 调用默认构造函数
    Widget w2 = std::move(w1); // 在这里调用移动构造函数
    
    return 0;
}

在这个例子中,`Widget w2 = std::move(w1);` 这一行代码将调用 `Widget` 类的移动构造函数。`std::move` 将 `w1` 转换为右值引用,然后移动构造函数接管 `w1` 的资源(在这个例子中是一个 `std::unique_ptr`)。注意,由于我们使用了 `std::unique_ptr`,它本身是不可复制的,只能被移动,所以删除了拷贝构造函数。

移动构造函数通常用于优化性能,特别是在处理大型对象或资源密集型对象时,因为它避免了不必要的资源复制,从而提高了效率。在移动构造函数之后,源对象通常处于一个有效但未定义的状态,直到它被销毁或重新赋值。
 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python案例 |地图绘制及分级着色

1、分级着色地图 分级着色地图常用于可视化地理数据&#xff0c;比如人口密度、经济数据、气候变化等。其原理是使用颜色或阴影的渐变来表示不同区域(如国家、省份、城市等)中的数据差异。例如&#xff0c;地图上的每个区域根据其代表的数值被着色&#xff0c;通常数值越大&am…

React Leaflet + React Pixi:双倍的快乐,我全都要

一篇实用性的文章&#xff0c;记录一下最近在自娱自乐使用 Leaflet 和 PixiJS 的过程中整的一个有意思的活&#xff0c;帮助我们使用 React 声明式的语法在 Leaflet 的图层上使用 PixiJS 绘图。 如果你对这些库和它们的用途都已有所了解&#xff0c;只想直接看代码的话&#xf…

今日指数项目day8实战权限管理功能(下)

3.4 权限添加按钮 1&#xff09;原型效果 2&#xff09;接口说明 功能描述&#xff1a; 权限添加按钮 服务路径&#xff1a; /api/permission 服务方法&#xff1a;Post请求参数格式: {"type":"1", //菜单等级 0 顶级目录 1.目录 2 菜单 3 按钮"t…

牛筋面,一口就爱上的神仙美食

宝子们&#x1f44b;&#xff0c;今天我一定要给大家种草一款超级好吃的美食 —— 食家巷牛筋面&#x1f60b;。&#x1f380;牛筋面真的是一种神奇的存在✨。它的口感 Q 弹有嚼劲&#xff0c;就像在你的嘴巴里跳舞一样&#x1f483;。每一根面条都裹满了浓郁的酱汁&#xff0c…

原生mybatis框架引入mybatisplus,调用接口时找不到原生Mapper自带的默认方法

1.yaml配置文件和Mapper注解基本上可以不用关注&#xff0c;因为mybatis能用就证明这俩多半是没有问题的 2.再看看是不是映射出了问题&#xff0c;像Namespace的空间包名和Mapper没有对上之类的 这个框架的问题是出在配置mybatis的config文件当中&#xff0c;原本的config文件用…

Unity 从零开始搭建一套简单易用的UGUI小框架 扩展与优化篇(完结)

一个通用的UGUI小框架就算是写完了&#xff0c;下面是一步步的思考与优化过程 Unity 从零开始搭建一套简单易用的UGUI小框架 基础分析篇-CSDN博客 Unity 从零开始搭建一套简单易用的UGUI小框架 功能撰写与优化篇-CSDN博客 从使用者的角度来整理一下可能会发出的疑问 0. Panel…

【微服务】springboot远程docker进行debug调试使用详解

目录 一、前言 二、线上问题常用解决方案 2.1 微服务线上运行中常见的问题 2.2 微服务线上问题解决方案 2.3 远程debug概述 2.3.1 远程debug原理 2.3.2 远程debug优势 三、实验环境准备 3.1 搭建springboot工程 3.1.1 工程结构 3.1.2 引入基础依赖 3.1.3 添加配置文…

YOLO11改进 | 注意力机制| 对小目标友好的BiFormer【CVPR2023】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 本文介绍了一种新颖的动态稀疏注意力机制…

C++,STL 029(24.10.13)

内容 一道练习题。 &#xff08;涉及string&#xff0c;vector&#xff0c;deque&#xff0c;sort&#xff09; 题目&#xff08;大致&#xff09; 有五名选手ABCDE&#xff0c;10个评委分别对每一个选手打分&#xff0c;去除最高分和最低分&#xff0c;取平均分。 思路&…

bat脚本banenr

飞出个未来班得 echo off echo .-. echo ( ) echo - echo J L echo ^| ^| echo J L echo ^| ^| echo J L echo …

Node.js概述

1. Node.js简介 Node.js是一个基于Chrome V8引擎的JavaScript运行环境。 地址&#xff1a;Node.js 中文网 1.1 Node.js中的JavaScript运行环境 &#xff08;1&#xff09;浏览器是JavaScript的前端运行环境 &#xff08;2&#xff09;Node.js是JavaScript的后端运行环境 …

vue3之插件

插件plugins是一种能为vue添加全局功能的代码,官网连接&#xff1a;https://cn.vuejs.org/guide/reusability/plugins.html 项目的src文件夹下新建plugins文件夹 新建i18n.js文件 插件是一个拥有install方法的对象 export default {install: (app, options)>{app.config.…

Linux中用java命令运行class文件提示“错误:找不到或无法加载主类”

1.问题&#xff1a; 很多时候&#xff0c;我们需要在Linux终端编译并运行普通Java程序&#xff0c;但是会遇到以下问题&#xff1a; 错误&#xff1a;找不到或无法加载主类” 2.问题原因及解决办法 其实原因很简单&#xff0c;可能由两方面造成。 原因一 java在运行.class文…

进制的介绍

一、进制介绍 对于整数&#xff0c;有四种表示方式&#xff1a;二进制&#xff1a;0,1 &#xff0c;满 2 进 1.以 0b 或 0B 开头。十进制&#xff1a;0-9 &#xff0c;满 10 进 1。八进制&#xff1a;0-7 &#xff0c;满 8 进 1. 以数字 0 开头表示。十六进制&#xff1a;0-9 …

损失函数篇 | YOLOv8更换损失函数之SlideLoss | 解决简单样本和困难样本之间的不平衡问题

前言:Hello大家好,我是小哥谈。SlideLoss是一种新颖的损失函数,可以有效地解决YOLO算法在处理小目标和密集目标时的问题。本文所做出的改进是在YOLOv8算法中引入SlideLoss损失函数。🌈 目录 🚀1.基础概念 🚀2.更换方法 🍀🍀步骤1:loss.py文件修改 🍀�…

C#源码安装ZedGraph曲线显示组件

在软件开发里,数据的显示,已经是软件开发的大头。 如果让数据更加漂亮地、智能地显示,就是软件的核心价值了。 因为不管数据千万条,关键在于用户看到图。因为一个图表,就可以表示整个数据的趋势, 或者整个数据的走向,数据频度和密码。所以图表显示是软件的核心功能,比如…

25.1 降低采集资源消耗的收益和无用监控指标的判定依据

本节重点介绍 : 降低采集资源消耗的收益哪些是无用指标&#xff0c;什么判定依据 通过 grafana的 mysql 表获取所有的 查询表达式expr通过 获取所有的prometheus rule文件获取所有的 告警表达式expr通过 获取所有的prometheus 采集器接口 获取所有的采集metrics计算可得到现在…

SpringBoot——静态资源访问的四种方式

1.默认的静态资源目录 /static /public /resources /META-INF/resources 动态资源目录&#xff1a;/templates 2.resources静态资源目录图片存放 3. 静态资源访问 3.1.通过路径访问静态资源 http://localhost:8080/a.jpg http://localhost:8080/b.jpg …

《深度学习》OpenCV 物体跟踪 原理及案例解析

目录 一、物体跟踪 1、什么是物体跟踪 2、步骤 1&#xff09;选择跟踪算法 2&#xff09;初始化跟踪器 3&#xff09;在每个视频帧上执行跟踪 4&#xff09;可选的重新初始化 3、原理 二、案例实现 1、完整代码 1&#xff09;使用方式 2&#xff09;运行结果 2、关…

用python做一个简单的画板

一&#xff0c;画板的介绍 画板&#xff08;Paint Board&#xff09;是一个提供用户绘图、涂鸦和创作的平台。现代数字画板通常是由软件程序实现的&#xff0c;具有多种功能。以下是画板的一些主要特征和功能&#xff1a; 1. 基本绘图工具 画笔和铅笔&#xff1a;用户可以选…