当前位置: 首页 > news >正文

C++值类别与移动语义

一、5秒速记法
std::string s = "Hi";   // s是左值(有名字,可复用)
func(std::move(s));      // 移动后s不再使用(通常置空)auto&& r = getBuffer();  // r绑定临时对象(资源转移)
二、三大必会操作
  1. 移动语义:避免拷贝大对象
// 1. 移动构造(实现资源转移)
class DataHolder {DataHolder(DataHolder&& other) noexcept : ptr(other.ptr), size(other.size) {other.ptr = nullptr;  // 关键:切断原对象所有权}
};
  1. 高效容器操作
 std::vector<BigData> vec;// 旧方式(低效)
-vec.push_back(BigData(1000));  // 构造+复制// 现代方式(高效)
+vec.emplace_back(1000);        // 原位构造
+vec.push_back(std::move(existObj)); // 转移已有对象
  1. 完美转发参数
template<typename T>
void relay(T&& arg) {  // 通用引用process(std::forward<T>(arg)); // 保持值类别
}relay(42);             // 传右值(触发移动)
relay(existObj);       // 传左值(保持原状态)
三、值类别速判表(开发中够用)
表达式类型能否取地址可复用性典型场景
左值 (lvalue)✔️✔️变量名、函数返回引用
将亡值 (xvalue)✔️std::move()返回值
纯右值 (prvalue)临时对象、字面量
四、三大工程铁律
  1. 移动后对象状态

    auto data = loadData(); // 加载资源
    process(std::move(data));// 此时data状态:
    assert(data.empty()); // 必须处于有效但不可预测状态
    
  2. noexcept强制要求

    // 移动构造必须标记noexcept
    DataHolder(DataHolder&&) noexcept;
    

    否则容器操作会退化到拷贝

  3. 工厂函数优化模式

    template<typename T, typename... Args>
    T create(Args&&... args) {return T(std::forward<Args>(args)...);
    }
    auto obj = create<BigObject>(1024); // 避免临时对象
    
五、常见避坑指南
  1. 不要移动基本类型

    int x = 10;
    int y = std::move(x); // 无意义,仍为复制
    
  2. 谨慎返回局部对象

    // 错误:阻止编译器优化
    BigObject func() {BigObject obj;return std::move(obj); // 禁用RVO
    }// 正确:依赖编译器优化
    BigObject func() {return BigObject(); // 自动触发RVO/NRVO
    }
    
  3. API设计原则

    // 接收右值参数(强制调用方转移所有权)
    void takeOwnership(BigData&& resource);// 接收任意值(保留值类别)
    template<typename T>
    void processResource(T&& resource);
    

推荐:C++学习一站式分享

http://www.dtcms.com/a/277064.html

相关文章:

  • linux shell从入门到精通(一)——初识Shell程序
  • opencv中contours的使用
  • Spring Boot RESTful API 设计指南:查询接口规范与最佳实践
  • Docker从环境配置到应用上云的极简路径
  • 【Docker基础】Dockerfile指令速览:文件与目录操作指令详解
  • 【深度学习新浪潮】什么是新视角合成?
  • Python----OpenCV(图像分割——彩色图像分割,GrabCut算法分割图像)
  • 【Linux】线程机制深度实践:创建、等待、互斥与同步
  • ARC 02 runner scale set chart:对接集群与 Github Action 服务器
  • Linux|服务器|二进制部署nacos(不是集群,单实例)(2025了,不允许还有人不会部署nacos)
  • 速通TypeScript装饰器
  • 【windows办公小助手】比文档编辑器更好用的Notepad++轻量编辑器
  • 机器学习sklearn入门:使用KNN模型分类鸢尾花和简单调参
  • 分类问题-机器学习
  • 「小程序开发」项目结构和页面组成
  • Http与Https区别和联系
  • 13. Flink 高可用机制简述(Standalone 模式)
  • 单页面和多页面的区别和优缺点
  • phpMyAdmin:一款经典的MySQL在线管理工具又回来了
  • 数学建模:评价决策类问题
  • 【nRF52832】【Ble 1】【低功耗蓝牙简介】
  • UML类图完全解读
  • 【C++详解】STL-priority_queue使用与模拟实现,仿函数详解
  • es里的node和shard是一一对应的关系吗,可以多个shard分配到一个node上吗
  • 板凳-------Mysql cookbook学习 (十一--------9)
  • 什么时候需要用到 multiprocessing?
  • Java集合框架深度解析:LinkedList vs ArrayList 的对决
  • 完整 Spring Boot + Vue 登录系统
  • 决策树学习
  • Spring Cloud Gateway 实战指南