c++ - 使用方法是否总是意味着通过“this”指针间接访问成员字段?
问题描述
我想知道这种类型的事情是否属于编译器的优化范围。从我从这次谈话中收集到的内容来看,甚至std::unique_ptr
不是真正的“零成本”,部分原因是指针的隐式间接this
在将实际底层指针传递给唯一指针的成员函数方面发挥了作用。
在将成员字段传递给类的方法时是否总是存在引用,或者编译器是否可以看到,说这个方法不使用某些字段并且不修改其余字段,所以它只会按值传递它们?
解决方案
谈话内容似乎有些误解。有一个关于为什么unique_ptr
不是“零成本”的讨论。然而,该讨论集中在一个具体案例,即所有权转让。一方面,既然存在有成本的情况,那确实unique_ptr
不是零成本。另一方面,这个结论具有误导性,因为它听起来就像说它是零成本一样包罗万象。更准确的描述将结合这两种观点:unique_ptr
可以零成本替代原始指针,但并非总是如此。
Aunique_ptr
可以是零成本。谈话结束时问答环节的第一个问题解决了这个问题(从 36:36 开始)。的大多数成员函数smart_ptr
都很简单,可以被任何理解模板语法的 C++ 编译器内联。没有与this
指针和成员函数相关的开销。如果您从不转让所有权,请继续将其unique_ptr
视为零成本。
所有权转移时会产生额外的成本。该演讲特别关注将 aunique_ptr
作为参数传递给函数。这明确地赋予了被调用函数对指针指向的任何内容的所有权。它还需要额外的运行时成本(如果原始指针版本缺乏异常安全性,则需要额外的两个成本)。
额外的成本不是 C++ 语言固有的,而是来自常用的 ABI(应用程序二进制接口)。ABI 在低级别(想想汇编)定义参数如何传递给函数。T*
根据这个约定,和之间有一个重要的区别unique_ptr<T>
– 前者是原始类型,而后者是类的实例。如果我正确理解了这部分谈话,ABI 要求将原始类型直接放在调用堆栈中(可能简单地存储在寄存器中),而类实例必须存在于主内存中,并且直接放置指向实例的指针在堆栈中/可能在寄存器中。是的,即使对象是按值传递的。为什么?因为这就是公约所要求的。(有更好的理由,但它们与当前主题无关。)为了让动态库之类的东西起作用,需要有一个约定,而这个 ABI 就是我们所拥有的。
结果是原语得到了优惠待遇,使它们更快。当您将函数的参数从指针切换到类实例时,会产生运行时成本(大小未知——它可能微不足道)。这是unique_ptr
在所有情况下都无法实现零成本的成本。在许多常见情况下是零成本,但在函数接受unique_ptr
参数时则不然。
推荐阅读
- python - Tkinter - 如何更改默认笔记本边框颜色?
- windows - 如果超过一分钟的 Windows 批处理文件,则退出循环
- flutter - firebase 消息传递和flutter sdk 驱动程序版本解决失败
- python - 发送 ctrl+c 按键需要 0.5 秒才能运行。如何加快速度?
- mysql - 如果数据类型是 Char(1),如何处理 Mysql 中文本文件中的 null?
- android - FaceDetector 没有通过 FaceDetector.release() 释放
- apache-kafka - 卡夫卡生产者保证
- r - 如何使用 ggplot2 在 R 中为多个 y 系列制作线性拟合线?
- java - 有没有办法将鼠标坐标移动到 JFrame 的标题?
- apache-tika - Apache TIKA - MediaDataBox iso 文件