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

c++的引用

示例

方式1:
std::vector<PjOpd> _expr_opds; 
std::vector<PjOpd> _pj_opds;
auto &opd = _expr_opds[expr_id];
_pj_opds.push_back(opd);
方式2:
std::vector<PjOpd> _expr_opds; 
std::vector<PjOpd> _pj_opds;
auto opd = _expr_opds[expr_id];
_pj_opds.push_back(opd);
两种实现方式的差别?

分析

你提出的两个代码片段(**方式1 和 方式2**)在语义和行为上有显著的区别,尤其是在性能、对象拷贝以及后续修改对原数据的影响方面。

---

## 🧪 一、代码回顾

### ✅ 方式1:使用引用 `auto &`

```cpp
std::vector<PjOpd> _expr_opds; 
std::vector<PjOpd> _pj_opds;

auto &opd = _expr_opds[expr_id];  // 引用
_pj_opds.push_back(opd);         // 拷贝进新 vector
```

### ✅ 方式2:不使用引用 `auto`

```cpp
std::vector<PjOpd> _expr_opds; 
std::vector<PjOpd> _pj_opds;

auto opd = _expr_opds[expr_id];  // 拷贝构造
_pj_opds.push_back(opd);        // 再次拷贝进新 vector
```

---

## 📊 二、对比分析

| 特性 | 方式1(`auto &`) | 方式2(`auto`) |
|------|------------------|----------------|
| `opd` 类型 | `PjOpd&`(引用) | `PjOpd`(值拷贝) |
| 是否从 `_expr_opds` 中拷贝元素? | 否(只是引用) | 是(一次拷贝) |
| `push_back` 是否再次拷贝? | 是(两次拷贝总) | 是(两次拷贝总) |
| 性能影响 | 更高效(避免一次拷贝) | 多一次拷贝,效率略低 |
| 修改 `opd` 是否影响 `_expr_opds`? | 是(因为是引用) | 否(因为是拷贝) |
| 安全性 | 若 `_expr_opds` 被修改或重新分配内存,引用可能失效 | 更安全,与原始 vector 无关 |

---

## 🔍 三、详细解释

### ✅ 方式1:`auto &opd = _expr_opds[expr_id];`

- 这是一个 **引用绑定到 `_expr_opds` 中的某个元素**;
- 然后调用 `_pj_opds.push_back(opd)` 时,会将该元素 **拷贝一份** 到 `_pj_opds`;
- 所以总共发生了一次拷贝(不是两次);
- 如果你之后修改了 `opd`,那么 `_expr_opds[expr_id]` 的值也会被修改;
- 适用于:你想操作原始数据,并将其拷贝到另一个容器中;

### ✅ 方式2:`auto opd = _expr_opds[expr_id];`

- 这是一个 **拷贝构造**,把 `_expr_opds[expr_id]` 的值拷贝了一份到局部变量 `opd`;
- 然后再通过 `push_back(opd)` 把这个拷贝再拷贝一份到 `_pj_opds`;
- 所以总共发生了 **两次拷贝**;
- 修改 `opd` 不会影响 `_expr_opds`;
- 适用于:你想操作副本,不影响原始数据;

---

## 📌 四、推荐写法(更高效)

如果你只打算拷贝一次,可以这样写:

```cpp
_pj_opds.push_back(_expr_opds[expr_id]);
```

这等价于方式1的效果,但更简洁,也避免了中间变量的冗余。

---

## 🧠 五、何时选择哪种方式?

| 使用场景 | 推荐方式 |
|----------|----------|
| 只想拷贝一次,不需要修改原 vector 中的数据 | `push_back(_expr_opds[expr_id])` |
| 需要修改原 vector 中的对象 | 方式1(`auto &opd`) |
| 想操作副本,不影响原数据 | 方式2(`auto opd`) |

---

## ✅ 六、总结表格

| 对比维度 | 方式1(引用) | 方式2(值拷贝) |
|----------|---------------|----------------|
| 是否拷贝原始数据 | 否 | 是 |
| push_back 拷贝次数 | 1 次 | 2 次 |
| 修改 `opd` 是否影响 `_expr_opds` | 是 | 否 |
| 性能 | 更优 | 略差 |
| 安全性 | 注意 vector 扩容导致引用失效 | 更安全 |
| 推荐使用 | 当需要操作原始数据时 | 当只需要副本时 |

http://www.xdnf.cn/news/12135.html

相关文章:

  • 26考研 | 王道 | 计算机组成原理 | 三、存储系统
  • 数据质量是什么意思?怎样做好数据质量监控?
  • 【Flask】:轻量级Python Web框架详解
  • 解决ts报错找不到vue组件,Module “d:src/views/quota/logicpoolinfo/components/add
  • stm32_GPIO
  • 63、.NET 异常处理
  • Honor of Kings 2025.06.05
  • 如何自定义一个 Spring Boot Starter?
  • 手撕 K-Means
  • 20250605车充安服务器受木马攻击导致服务不可用
  • 【SSM】SpringBoot学习笔记1:SpringBoot快速入门
  • 02 Deep learning神经网络的编程基础 逻辑回归--吴恩达
  • ES6中的Map与Set数据结构的简单应用
  • 如何轻松将视频从安卓设备传输到电脑?
  • QT开发技术【ffmpeg + QAudioOutput】音乐播放器 完善
  • Struts2漏洞由浅入深
  • Python数据类型与运算符全解析-Python数据挖掘可视化分析
  • DASCTF
  • QT使用WxSQLite3打开加密数据库并查询
  • 开始在本地部署自己的 Gitea 服务器
  • 【QT】使用QT帮助手册找控件样式
  • 构建云原生安全治理体系:挑战、策略与实践路径
  • 如果科技足够发达,是否还需要维持自然系统(例如生物多样性)中那种‘冗余’和‘多样性’,还是可以只保留最优解?
  • 概述侧边导航的作用与价值
  • Socket编程UDP\TCP
  • tcp/udp
  • 2025年渗透测试面试题总结-腾讯[实习]玄武实验室-安全工程师(题目+回答)
  • Elasticsearch最新入门教程
  • VSCode主题定制:CSS个性化你的编程世界
  • 自动化办公集成工具:一站式解决文档处理难题