如何理解Move参数中的const Source和var Dest

C++ std::move 移动语义:从值类别到性能优化的核心机制 在 C++ 编程中,资源管理和性能优化是核心议题。传统深拷贝在处理大型对象(如容器、字符串)时开销巨大,影响程序效率。移动语义(Move Semantics)的引入正是为了解决这一问题,它通过资源所有权的转移而非复制来提升性能。其原理基于 C++11 对值类别的细化,将表达式分为左值、纯右值和将亡值(xvalue)。std::move 本质上是一个类型转换器,它将左值无条件转换为将亡值,从而为移动构造函数和移动赋值运算符的调用创造条件。这项技术的核心价值在于实现高效、零开销的资源转移,广泛应用于标准库容器( 阅读详情
如何理解Move参数中的const Source和var Dest

总结作者:SkyJacker
贡献者:小峰,LiuXiao
http://www.cnpack.org
CnPack IV  QQ Group: 130970
2007-01-31
(转贴请注明作者、出处且保持完整)

Q:
procedure Move(const Source; var Dest; Count: Integer);
问一下这里的参数Source和Dest没有说明数据类型,那具体应该如何使用啊?

var
  xx, yy: array [0..6] of Char;
begin
  FillChar(xx, 7, #0);
  xx := 'abcdef';
  Move(xx, yy, 4);
  Move(xx[0], yy[0], 4)
  //上面这两条语句有什么区别
end;  

A:

xx, yy就是一块数据。
xx[0] 就是这块数据的第一个字符
这两个的起始地址相同,因此move的结果也相同了。  

测试代码:
procedure TForm1.btnXClick(Sender: TObject);
var
  xx, yy: array [0..6] of Char; // 内容存在栈里
  a: array of Char; // 内容存在堆里,这就可以理解为什么动态数组a代表的是字符串的指针了
begin
  SetLength(a, 10);
  FillChar(xx, 7, #0);
  xx := 'abcdef';
  a[0]:='A';
  a[1]:='B';
  Move(xx, yy, 4);
  Move(xx[0], yy[0], 4);
  Move(xx,a[0],4);
end;  

顺便再解释一下 Move 的 Pascal 源码(Windows XP Sp2 Delphi6 + Update2 ):

procedure Move( const Source; var Dest; count : Integer );
{$IFDEF PUREPASCAL}
var
  S, D: PChar;
  I: Integer;
begin
  S := PChar(@Source);
  D := PChar(@Dest);
  if S = D then Exit;
  if Cardinal(D) > Cardinal(S) then //精华1:小心,别覆盖了Source
    for I := count-1 downto 0 do
      D[I] := S[I]
  else
    for I := 0 to count-1 do
      D[I] := S[I];
end;

{$ELSE}
asm
{     ->EAX     Pointer to source       }
{       EDX     Pointer to destination  }
{       ECX     Count                   }

        PUSH    ESI
        PUSH    EDI

        MOV     ESI,EAX
        MOV     EDI,EDX

        MOV     EAX,ECX

        CMP     EDI,ESI
        JA      @@down
        JE      @@exit

        SAR     ECX,2           { copy count DIV 4 dwords       }
        JS      @@exit

        REP     MOVSD

        MOV     ECX,EAX         //精华2: 放之四海皆准。
        AND     ECX,03H        
        REP     MOVSB           { copy count MOD 4 bytes        }
        JMP     @@exit

@@down:
        LEA     ESI,[ESI+ECX-4] { point ESI to last dword of source     }
        LEA     EDI,[EDI+ECX-4] { point EDI to last dword of dest       }

        SAR     ECX,2           { copy count DIV 4 dwords       }
        JS      @@exit
        STD
        REP     MOVSD

        MOV     ECX,EAX        
        AND     ECX,03H         { copy count MOD 4 bytes        }
        ADD     ESI,4-1         { point to last byte of rest    }
        ADD     EDI,4-1
        REP     MOVSB
        CLD
@@exit:
        POP     EDI
        POP     ESI
end;
{$ENDIF}

注:

C/Pascal等高级语言里头的指针其实是一个存储了地址的内存单元,其存储的内容(是一个地址)所指的地方才是这个指针所指的内容。
而I:Integer只是一个内存单元,I的内容是整型变量,@I才能得到I的地址。

Pascal中的无类型变量,相当于C中的void。参数const Source; var Dest; 可以理解为两块内存区域。这两参数调用时在汇编中的实现,便是将Source和Dest的“地址值”作为参数传入,而并非传入这两变量本身。

但在函数内部的Pascal实现中,Source是传入的地址再指了一次而得到的结果,因此仍然代表传进来之前的Source。欲取得汇编中实现时传入来的地址,则需要用@Source。也就是说,这个var封装并且隐藏了函数被调用时传入的取地址操作和函数体内部使用时指了一次的操作。

 
C++11 移动语义陷阱:5个常见错误与std::move的正确使用 本文深入探讨C++11移动语义的常见陷阱,包括std::move误用、移动构造与拷贝构造混淆等问题,并提供5个典型错误场景的解决方案。通过代码实例和最佳实践,帮助开发者避免资源管理错误,提升程序性能与安全性。 阅读详情

相关推荐

C++移动语义与完美转发:从值类别到高效编程实践

在C++编程中,资源管理和参数传递是影响性能的关键因素。理解值类别(左值、右值、将亡值)和引用类型是掌握现代C++的基础,它们定义了对象的身份和可移动性。基于这一原理,C++11引入了移动语义,通过资源所有权转移而非复制来提升效率,其核心是移动构造函数和移动赋值运算符的实现。这一技术价值在于大幅减少了动态内存、文件句柄等资源管理的开销。在应用场景上,移动语义广泛应用于标准库容器操作、工厂函数和返回值优化。而完美转发则解决了泛型编程中参数传递的痛点,通过通用引用和引用折叠规则,配合std::forward保持

weixin_34326179的博客 386

C++11 自定义Move构造函数(Move Constructor)和Move赋值运算符(Move Assignment Operators)

在C++11的标准当中,引入了右值的概念以及跟右值密切相关的Move语义,由此C++的类定义中也多了2个成员函数:Move构造函数和Move赋值运算符。这篇文章将讨论如何为我们自己的类编写Move 构造函数和Move赋值运算符。 class IntArray 是一个Int 类型的数组,它的类定义如下: #pragma once #include <iostream> #inclu...

姜的理想国 6775

C++移动语义误用详解:五大典型场景与避坑指南

移动语义是现代C++中用于优化资源管理、提升程序性能的核心机制,其本质是所有权的转移而非资源的简单复制。理解其底层原理对于编写高效、安全的代码至关重要,尤其在涉及动态内存、文件句柄等昂贵资源管理时,正确的移动操作能显著减少深拷贝开销。然而,误用移动语义可能导致数据损坏、悬空指针等难以调试的问题,严重影响软件稳定性与可维护性。本文聚焦于移动语义在实际工程中的应用陷阱,通过剖析返回局部变量、通用引用转发、移动后使用源对象等高频误用场景,结合C++11/14/17标准特性,提供系统的避坑指南与最佳实践,帮助开发者

weixin_33994429的博客 381

移动一个const对象会发生什么?

我们知道,通过移动操作从一个对象中“窃取”数据的时候,被窃取的那个对象会被修改。这也是为什么移动构造函数要声明成Test(Test&&)的原因。当我们对一个const对象进行移动时,直觉上可能会认为,无法编译通过。毕竟移动操作会修改源对象,但是原对象又是一个const对象,很矛盾。但是实际上上面的代码可以编译通过。但是最好不要对const对象应用移动操作,如果这个对象尺寸很大的话,拷贝操作的代价很高。可见,如果试图对一个const对象进行移动操作,最终会使用拷贝来作为一个变通方法。

tianyingang的博客 720

西门子PLC填充块指令FILL_BLK与UFILL_BLK应用详解

在工业自动化编程中,内存操作是影响程序效率和稳定性的核心技术。理解连续数据块的高效管理原理,对于优化PLC程序性能至关重要。通过块操作指令,工程师可以实现批量数据初始化、缓冲区管理等功能,显著提升代码执行效率。在西门子TIA Portal环境中,FILL_BLK和UFILL_BLK指令正是实现这一技术价值的关键工具,广泛应用于设备初始化、上位机通讯数据准备等场景。特别是在处理DB块地址操作和优化访问机制时,这两个指令的选择与正确使用直接关系到程序的可靠性。本文深入解析这两个指令的差异,帮助工程师掌握数据块填

weixin_34007020的博客 416

【C++11保姆级教程】移动构造函数(move constructor)和移动赋值操作符(move assignment operator)

在C++11标准中引入了移动语义的概念,通过移动构造函数和移动赋值操作符,我们可以更高效地管理对象的资源。本文将以通俗易懂的方式详细解释移动构造函数和移动赋值操作符的概念,并通过生动的比喻帮助读者更好地理解这两个概念。当我们需要在C++中处理大量数据或动态分配的对象时,移动构造函数和移动赋值操作符成为了重要的工具。它们是C++11引入的特性,旨在提高程序的性能和效率。

m0_62599305的博客 1万+

std::move一个const对象

类型,这意味着移动构造函数或移动赋值操作符无法应用于这个对象,因为它们通常要修改源对象,而。本身只是将对象的类型转换为右值引用,使得可以使用移动语义。对象的结果,通常会退化到使用拷贝构造或拷贝赋值,就像没有使用。修饰符强制性地从该对象中移除来实现,方法是使用。,即便转换为右值引用,依然会被视为。的语义,可能会引发未定义的行为。对象实际上不会移动该对象。但需要注意,这样做会违反。

折花刀的博客 854

【程序化天空盒】过程记录01:日月 天空渐变 大气散射

在做一个仿照原神的天空盒,写文章作为技术总结和记录。

qq_41835314的博客 6742

深入理解Move Constructor和Move Assignment

    之前的一篇博客讲了左值引用和右值引用,并且细致地说到了右值实际上就是“一闪而过”的结果,它是程序在计算时候的一个中间量,这个中间量如果我们能够有效的利用上,那么我们再创建对象(Constructor)的时候或是给已有对象(Assignment)赋值的时候很多资源就不用再重新申请了,直接把右值的资源“steal”过来。不要小看这一步的改变,如果你的程序频繁地创建对象,并且一个对象创建需要进行...

zhangsj1007的博客 6929

MR2数据集实战:5步搞定多模态谣言检测模型训练(附完整代码)

本文详细介绍了如何使用MR2多模态数据集构建高精度谣言检测系统,涵盖环境配置、数据准备、多模态特征工程、模型架构设计、训练调优及部署优化等5个关键步骤。通过双线性融合技术处理文本、图像和网页三模态数据,解决特征对齐和模态冲突等工程难题,并提供完整代码实现和性能优化方案。

weixin_42657024的博客 240

地震数据可视化必备:5分钟读懂SEGY道头字段全解析(含坐标定位指南)

本文深入解析了SEGY文件格式中道头坐标字段的提取与可视化方法。针对地震数据处理中的常见痛点,详细介绍了sx/sy、gx/gy等关键坐标字段的二进制解析、比例因子应用、单位转换及常见问题解决方案,并提供了实用的Python代码示例,帮助开发者实现从SEGY文件到三维空间可视化的完整流程。

echo99的专栏 1012

move函数的用法

delphi中move函数的正确理解 收藏 我们能看到以下代码var pSource,pDest:PChar;     len: integer;.......................//一些代码Move(pSource,pDest,len); //错误Move(pSource^,pDest^,len); //正确看起来确实好像是传值,而不是传地址,但是各位别忘了,这不是C,C++,而是D...

weixin_33690963的博客 6436

【鸿蒙游戏上架审核规范指南】

华为鸿蒙游戏上架审核规范指南摘要

weixin_44161102的博客 924

Day1-右值引用与移动语义:从拷贝到移动的范式革命

场景做法原因返回局部对象return obj;依赖 NRVO/隐式移动,不要加std::move返回临时对象return T{};prvalue,C++17 强制消除拷贝向容器插入右值避免拷贝,直接移动容器间转移元素当元素确定不再需要时移动构造函数标记noexcept保证 STL 容器 realloc 时选择移动移动赋值运算符包含自赋值检查防止delete[]后资源丢失在类中声明析构函数同时声明移动操作避免编译器不生成默认移动操作参数按值传递调用方决定拷贝还是移动。

如风逝去 341

增量式PID的P和I怎么理解(一)

增量式PID的P、I理解之推翻片 据我所知的资料里关于PID三个参数的理解是这样的:(我这里只说P和I,先不说D) P的作用:比例P可以加快系统调节速度,P过小调节时间变长,响应性不够,P越大响应性越高超调也越严重,过大的P会使系统振荡。 I的作用:消除静差,提高控制精度,I越大越滞后,过大会使系统振荡。 ...

fangchenglia的博客 1万+

无人机芯片模块技术要点分析

恶劣环境下信号稳定性:无人机在恶劣环境下工作时,遥感系统采集的信号往往很不稳定,视频信号处理芯片需要具备强抗干扰能力,能辨别脉冲脉宽为50ns以上、幅度为0V~4.5V的输入信号。这种架构能兼顾强大的运算能力和灵活的接口控制。芯片小型化:麻省理工学院的研究人员已设计出仅20平方毫米的微型芯片,可处理无人机飞行所需的惯性数据和相机图像,为微型无人机的发展奠定了基础。光子集成芯片(PIC) :研究显示,与电子芯片相比,光子计算芯片在延迟、计算容量和能效上都有数量级的提升,有望解决当前无人机系统的计算瓶颈。

YUNZHUO666的博客 1404

右值引用与移动语义:从拷贝到移动的范式革命

std::cout << "Buffer 移动赋值 from size=" << size_ << "\n";std::cout << "Buffer 移动构造 from size=" << size_ << "\n";

如风逝去 367

cannot import name ‘BUFSIZE‘ from ‘numpy‘ 解决方案

本文主要介绍了cannot import name ‘BUFSIZE’ from ‘numpy’ 解决方案,希望能对使用numpy的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 22万+

BabelDOC:如何把外文 PDF 论文变成双语对照版

BabelDOC 是一个命令行运行的 PDF 论文翻译与双语对比工具:它解析英文论文的排版、文本与公式,调用 OpenAI 兼容模型生成中文译文,再输出保留原排版的双语 PDF。适合需要大量阅读外文文献的科研读者,以及想把翻译能力集成进自己程序的开发者。 ## 📌 它解决的现实痛点 [![BabelDOC 双语对照排版效果预览,左英文原文右中文翻译](https://raw.gitcode.

gitblog_00865的博客 497

微信小程序 - {errCode: 10008, errno: 1500104, errMsg: “writeBLECharacteristicValue:fail write characteris

微信小程序errCode: 10008, errno: 1500104, errMsg: "writeBLECharacteristicValue:fail write characteristics error. 10008, errMsg=The value's length is invalid.",uni-app微信小程序报错,uniApp小程序调用蓝牙api报错,向低功耗蓝牙设备的某个特征写入数据时错误,UniApp微信小程序蓝牙API调用报错10008解决方案,蓝牙设备进行通信时,向设备写入数据

🏆 前端领域优质创作者 4431

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C++11右值引用与移动语义:高性能编程的核心机制

在C++编程中,对象拷贝是常见的性能瓶颈,尤其是在处理容器、字符串或自定义资源管理类时,深拷贝会带来显著的开销。为了解决这一问题,C++11引入了右值引用和移动语义,它们通过识别临时对象(右值)并转移其资源,避免了不必要的复制。这一机制不仅提升了标准库容器(如std::vector和std::string)的性能,还为自定义类的资源管理提供了高效方案。移动语义的核心在于移动构造函数和移动赋值运算符,它们允许将即将销毁的对象的资源“窃取”过来,从而减少内存分配和拷贝操作。在实际应用中,结合完美转发和noexc

weixin_30381317的博客 500

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Python命令行工具开发:argparse模块从入门到实战

命令行接口(CLI)是程序与用户交互的重要方式,它允许用户通过终端输入参数来控制程序行为。其核心原理在于解析命令行参数,将用户输入转换为程序可处理的数据结构。在Python生态中,标准库的argparse模块提供了声明式配置的解决方案,能自动完成参数解析、验证、类型转换和帮助文档生成,极大提升了脚本的健壮性和可维护性。这一技术价值在于让开发者能够快速构建专业、用户友好的命令行工具,降低使用门槛。无论是数据处理、自动化脚本还是项目脚手架,都需要处理复杂的参数输入场景。通过掌握argparse的位置参数、可选参

weixin_30416871的博客 345

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

深入解析C++ STL迭代器:从核心概念到工程实践

迭代器是泛型编程中的核心抽象概念,它提供了一种统一访问容器元素的方式,屏蔽了底层数据结构的差异。其工作原理是通过定义一组通用的操作接口(如递增、解引用),使得算法能够独立于具体容器实现。这一机制的技术价值在于实现了数据结构和算法的高效解耦,极大地提升了代码的复用性和泛化能力。在应用场景上,迭代器不仅是C++ STL(标准模板库)的基石,连接着容器与算法,也是实现如**迭代器适配器**(如反向迭代器、插入迭代器)和**迭代器萃取**机制的关键,后者使得算法能在编译期根据迭代器能力选择最优实现。理解迭代器的分类

diaoqu4574的博客 363

C++泛型编程实战:从模板基础到STL应用与元编程

泛型编程是编写不依赖具体数据类型的代码范式,其核心原理是通过模板实现编译期多态,从而提升代码复用性和类型安全性。这一技术价值在于能够构建高度抽象且性能优异的可复用组件,广泛应用于高性能计算库、游戏引擎和通用框架开发。在C++中,模板机制包括函数模板、类模板和变参模板,配合STL容器与算法,形成了标准化的泛型实践体系。本文聚焦C++实战,通过解析模板特化、SFINAE等高级技巧,并结合STL的迭代器与算法设计,深入探讨如何规避代码膨胀、优化编译错误,并引入C++20概念约束以提升接口清晰度,为开发者提供从基础

weixin_34259232的博客 419

C++字符序列:从内存编码到std::string与string_view高效实践

字符序列是编程中处理文本数据的基础概念,涉及内存中字节的组织与解释。其核心原理在于通过特定编码规则(如ASCII、UTF-8)将字符映射为二进制数据,并在内存中连续存储。理解这一原理对实现高效、安全的文本处理至关重要,直接关系到程序的内存安全与性能。在C++工程实践中,字符序列的技术价值通过多种工具体现:C风格字符串提供底层控制但易出错;std::string通过自动内存管理(包括**短字符串优化SSO**)提升了开发效率与安全性;而C++17引入的**std::string_view**则实现了零成本的只

weixin_30432579的博客 642

C++指针深度解析:从内存模型到智能指针的实战指南

指针是计算机编程中用于直接操作内存地址的核心概念,它本质上是一个存储内存地址的变量。理解指针需要从计算机内存模型入手,内存被组织为线性字节序列,每个字节拥有唯一地址,变量则是具名内存区域。指针通过存储地址实现了对数据的间接访问,这一机制带来了动态内存管理、高效函数参数传递、硬件直接访问等关键技术价值,广泛应用于操作系统、数据库、游戏引擎等高性能场景。在C++中,指针语法涉及声明、取地址(&)、解引用(*)等操作,同时需警惕野指针、内存泄漏等常见问题。现代C++通过智能指针(如unique_ptr、share

cuiyingchan0663的博客 395
上一篇: 如何获取多核、多cpu系统中指定cpu的序列号
下一篇: 关于函数调用中形参的分析
skyjacker
博客等级 码龄23年 11粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值